Adding specific data for each section in UITableView - Swift - ios

I have a Table view with data compiled from a Dictionary array where the keys are the section headers:
var data: Dictionary<String,[String]> = [
"Breakfast": ["Oatmeal","Orange Juice"],
"lunch": ["Steak","Mashed Potatoes","Mixed Veg"],
"Dinner": ["Chicken","Rice"],
"Snack": ["Nuts","Apple"]
]
var breakfastCalories = [100,200,300]
var lunchCalories = [300,400,500]
var DinnerCalories = [600,700,800]
var breakfast = 0
Below is the code for populating the Table View
override func viewDidLoad() {
super.viewDidLoad()
for value in breakfastCalories as NSArray as! [Int]{
breakfast = breakfast + value
}
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return data.count
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// Return the number of rows in the section.
let sectionString = Array(data.keys)[section]
return data[sectionString]!.count
}
func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
let sectionString = Array(data.keys)[section]
return sectionString
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! TableViewCell
let sectionString = Array(data.keys)[indexPath.section]
cell.caloriesLabel.tag = indexPath.row
cell.caloriesLabel.text = String(breakfastCalories[indexPath.row])
cell.foodLabel.tag = indexPath.row
cell.foodLabel.text = data[sectionString]![indexPath.row]
return cell
}
func tableView(tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
let footerView = UIView(frame: CGRectMake(0, 0, tableView.frame.size.width, 40))
// self.myTableView.tableFooterView = footerView;
let label = UILabel(frame: CGRectMake(footerView.frame.origin.x - 15, footerView.frame.origin.y, footerView.frame.size.width, 20))
label.textAlignment = NSTextAlignment.Right
label.text = "Total Calories: \(breakfast) "
footerView.addSubview(label)
return footerView
}
func tableView(tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 20.0
}
My question is, how can I add the calories array for each section? so for breakfast, it will contain the calories from the breakfastCalories array, lunch section for the lunchCalories array etc.
I may be overthinking this but I can't get my head around this problem
Thanks
On the right the values are grabbed from the breakfastCalories however as mentioned each section contain the calories from the breakfastCalories array, lunch section for the lunchCalories array etc.

You could structure your calories similar to your data property, with similar keys:
var calories: Dictionary<String,[Int]> = [
"Breakfast": [100,200,300],
"lunch": [300,400,500],
"Dinner": [600,700,800]
]
That way you can pull out the right calories depending on what section you are showing and add them up to create a total for you label to show: (Add this where you create your footerView and just above where you set your label.text)
let dataKeysArray = Array(data.keys)[section]
let sectionString = dataKeysArray[section]
let mealCalories = calories[sectionString]
var totalCalories: Int = 0
for calories in mealCalories {
totalCalories += calories
}
label.text = "Total Calories: \(totalCalories) "

Related

I'm Creating an demo on Expandeble Tableview, Expanding is working Fine... But facing issue while didselect row is tapped

Expanding and Collapsing is working fine tableview, Only facing issue while didselect row is tapped, I'm getting same index evry time after selecting a row. I'm getting the same out put, I want to pass the data to next view but output isn't working properly.
Here's My Details...
My OutPut
My Model
struct ItemList {
var name: String
var items: [String]
var collapsed: Bool
init(name: String, items: [String], collapsed: Bool = false) {
self.name = name
self.items = items
self.collapsed = collapsed
}
}
My ViewController Class
class ViewController: UIViewController {
#IBOutlet weak var tableView: UITableView!
var sections = [ItemList]()
var items: [ItemList] = [
ItemList(name: "Mac", items: ["MacBook", "MacBook Air"]),
ItemList(name: "iPad", items: ["iPad Pro", "iPad Air 2"]),
ItemList(name: "iPhone", items: ["iPhone 7", "iPhone 6"])
]
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
}
}
TableView Extension
extension ViewController:UITableViewDelegate,UITableViewDataSource{
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 60
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerHeading = UILabel(frame: CGRect(x: 5, y: 10, width: self.view.frame.width, height: 40))
let imageView = UIImageView(frame: CGRect(x: self.view.frame.width - 30, y: 20, width: 20, height: 20))
if items[section].collapsed{
imageView.image = UIImage(named: "collapse")
}else{
imageView.image = UIImage(named: "expand")
}
let headerView = UIView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: 60))
let tapGuesture = UITapGestureRecognizer(target: self, action: #selector(headerViewTapped))
tapGuesture.numberOfTapsRequired = 1
headerView.addGestureRecognizer(tapGuesture)
headerView.backgroundColor = UIColor.red
headerView.tag = section
headerHeading.text = items[section].name
headerHeading.textColor = .white
headerView.addSubview(headerHeading)
headerView.addSubview(imageView)
return headerView
}
func numberOfSections(in tableView: UITableView) -> Int {
return items.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
let itms = items[section]
return !itms.collapsed ? 0 : itms.items.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) ->
UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell")!
cell.textLabel?.text = items[indexPath.section].items[indexPath.row]
return cell
}
#objc func headerViewTapped(tapped:UITapGestureRecognizer){
print(tapped.view?.tag)
if items[tapped.view!.tag].collapsed == true{
items[tapped.view!.tag].collapsed = false
}else{
items[tapped.view!.tag].collapsed = true
}
if let imView = tapped.view?.subviews[1] as? UIImageView{
if imView.isKind(of: UIImageView.self){
if items[tapped.view!.tag].collapsed{
imView.image = UIImage(named: "collapsed")
}else{
imView.image = UIImage(named: "expand")
}
}
}
tableView.reloadData()
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let row = items[indexPath.row]
print("IndexPath :- \(row.name)")
}
}
If you look at the way you are setting the text in your cells in cellForRowAt:
cell.textLabel?.text = items[indexPath.section].items[indexPath.row]
You are saying:
get the ItemList object for indexPath.section from items array
get the String from that object's items array of this indexPath.row
However, in your didSelectRowAt:
let row = items[indexPath.row]
print("IndexPath :- \(row.name)")
You are saying:
get the ItemList object for indexPath.row from items array
print the .name property of that object
So, change your didSelectRowAt code to match your cellForRowAt logic:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let selectedString = items[indexPath.section].items[indexPath.row]
print("IndexPath :- \(selectedString)")
// or, for a little more clarity
let sectionObject = items[indexPath.section]
let rowItem = sectionObject.items[indexPath.row]
print("IndexPath :- \(indexPath) // Section :- \(sectionObject.name) // Item :- \(rowItem)")
}

Collapse other UITableViewCell when current cell is expanded

I am trying to expand my UITableViewCell and I can expand cells. But I want to collapse the UITableViewCell which are not selected.
What I am trying in code:
var expandedCells = [Int]()
#IBOutlet weak var tableVieww:UITableView!
#IBAction func buttonPressed(_ sender: AnyObject) {
// If the array contains the button that was pressed, then remove that button from the array
if expandedCells.contains(sender.tag) {
expandedCells = expandedCells.filter({ $0 != sender.tag})
}
// Otherwise, add the button to the array
else {
expandedCells.append(sender.tag)
}
// Reload the tableView data anytime a button is pressed
tableVieww.reloadData()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 20
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! exampleCell
cell.myButton.tag = indexPath.row
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
// Set the row height based on whether or not the Int associated with that row is contained in the expandedCells array
if expandedCells.contains(indexPath.row) {
return 212
} else {
return 57
}
}
You can maintain a variable for maintaining the selected index as below,
var expandedIndexPath: IndexPath?
Then update your tableView delegate as follows,
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
expandedIndexPath = indexPath // Update the expandedIndexPath with the selected index
tableView.reloadData() // Reload tableview to reflect the change
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
// Check wether expanded indexpath is the current index path and updated return the respective height
if expandedIndexPath == indexPath {
return 212
} else {
return 57
}
}
This should work fine.
1) First Create Bool Array variable
var isExpandArr = Array<Bool>()
2) Insert true at 0 index in ViewLoad()
isExpandArr.insert(true, at: 0)
3) Put Into cellForRowAt
cell.ToggleBT.addTarget(self, action: #selector(handleToggleBtn), for:.touchUpInside)
cell.ToggleBT.tag = indexPath.row
if isExpandArr[indexPath.row] == true{
cell.bottomrView.isHidden = false
}else{
cell.bottomrView.isHidden = true
}
4) set heightForRowAt
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return isExpandArr[indexPath.row] ? 204 : 60
}
5) put function
func handleToggleBtn(sender: UIButton){
print(sender.tag)
if isExpandArr.contains(true){
print("yes")
if let unwrappedIndex = isExpandArr.index(of: true){
isExpandArr[unwrappedIndex] = false
isExpandArr[sender.tag] = true
}
}
table.reloadData()
}
in #swift 2.3
Hope this will also helpful
For collapse and expand the header
define the variable above the viewDidLoad or within the class block
var headerIcon: UIImageView = UIImageView()
var sectionTitleArray : NSMutableArray = NSMutableArray()
var sectionContentEventTitleDict : NSMutableDictionary = NSMutableDictionary()
var sectionEventImagesDict : NSMutableDictionary = NSMutableDictionary()
var arrayForBool : NSMutableArray = NSMutableArray()
var arrFirstSectionItemTitle = ["Section 1 item Name 1","Section 1 item Name 2","Section 1 item Name 3","Section 1 item Name 4","Section 1 item Name 5","Section 1 item Name 6","Section 1 item Name 7"]
var arrFirstSectionItemImages = ["Section_1_icon_1","Section_1_icon_2","Section_1_icon_3","Section_1_icon_4","Section_1_icon_5","Section_1_icon_6","Section_1_icon_7"]
var arrSecondSectionItemTitle = ["Section 2 item Name 1","Section 2 item Name 2","Section 2 item Name 3","Section 2 item Name 4"]
var arrSecondSectionItemImages = ["Section_1_icon_1","Section_2_item_icon_2","Section_2_item_icon_3","Section_1_item_icon_4","Section_1_item_icon_5","Section_1_item_icon_6","Section_1_item_icon_7"]
var arrData: Array<Dictionary<String,AnyObject>> = Array<Dictionary<String,AnyObject>>()
#IBOutlet weak var tableList: UITableView!
in viewDidLoad() method write these lines of code
tableList.delegate = self
tableList.dataSource = self
tableList.backgroundColor = UIColor.getRGBColor(240, g: 240, b: 240)
let customView = UIView(frame: CGRectMake(0, 0, 200, 80))
customView.backgroundColor = UIColor.getRGBColor(240, g: 240, b: 240)
let customLine = UIView(frame: CGRectMake(0, 0, tblAllQuestion.frame.size.width, 1))
customLine.backgroundColor = UIColor.getRGBColor(240, g: 240, b: 240)
customView.addSubview(customLine)
tableList.tableFooterView = customView
now write the delegate and datasource methods as following:
//MARK: UITableViewDelegate AND UITableViewDataSource METHOD WITH SECTION
for number of sections to be collapsed and expand
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
print_debug(sectionTitleArray.count)
return sectionTitleArray.count
}
cell method:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("CELL_IDENTIFIER", forIndexPath: indexPath)as! CellAllQuestionFiqhVC
//let cellIdentifier = "CellAllQuestionFiqhVC"
// cell = self.tableList.dequeueReusableCellWithIdentifier(cellIdentifier)
let manyCells : Bool = arrayForBool .objectAtIndex(indexPath.section).boolValue
if (!manyCells) {
// cell.textLabel.text = #"click to enlarge";
}
else{
let group = self.arrData[indexPath.section]
let data: Array<Dictionary<String,AnyObject>> = group["data"]as! Array<Dictionary<String,AnyObject>>
cell.configCell(data[indexPath.row], instance: self)
}
return cell
}
number cell in a section:
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if(arrayForBool.objectAtIndex(section).boolValue == true){
let count1 = arrData[section]["data"]!
if count1.count != nil {
return count1.count
}
}
return 0;
}
the height of the section
func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 40
}
The height of the cell:
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
if(arrayForBool.objectAtIndex(indexPath.section).boolValue == true){
return 100
}
return 2;
}
to set header tappable:
func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerView = UIView(frame: CGRectMake(0, 0, tableView.frame.size.width, 40))
headerView.backgroundColor = UIColor.whiteColor()//Constant.kAPP_COLOR
headerView.tag = section
let headerString = UILabel(frame: CGRectMake(40/*tableView.frame.size.width/2-30*/, 10, tableView.frame.size.width, 18))
let headerLine = UIView(frame: CGRectMake(0, 39, tableView.frame.size.width, 1))
//UILabel(frame: CGRect(x: 20, y: 10, width: tableView.frame.size.width-10, height: 30)) as UILabel
//headerLine.text = sectionTitleArray.objectAtIndex(section) as? String
headerLine.backgroundColor = UIColor.getRGBColor(240, g: 240, b: 240)
headerView .addSubview(headerLine)
headerIcon = UIImageView(frame: CGRect(x: tblAllQuestion.bounds.maxX-30, y: 10, width: 8, height: 12)) as UIImageView
headerIcon.image = UIImage(named: "right_arrow")
headerView.addSubview(headerIcon)
let headerTapped = UITapGestureRecognizer(target: self, action: #selector(sectionHeaderTapped))
headerView.addGestureRecognizer(headerTapped)
return headerView
}
for rotate section icon on tapped on:
func rotateSectionIconOnTapped(indexTapped: Int) {
isActiveMap = false
if arrayForBool.objectAtIndex(indexTapped) as! NSObject == true {
print("toggle the icon at degree 90")
headerIcon.transform = CGAffineTransformMakeRotation(CGFloat(M_PI_2))
}
else if arrayForBool.objectAtIndex(indexTapped) as! NSObject == false {
print("toggle the ico at degree 0")
headerIcon.transform = CGAffineTransformMakeRotation(0)
}
}
action for section header tapped:
func sectionHeaderTapped(recognizer: UITapGestureRecognizer) {
//filterByCategoryIsOn = false
print("Tapping working")
print(recognizer.view?.tag)
//if recognizer.view!.tag != 2 {
let indexPath : NSIndexPath = NSIndexPath(forRow: 0, inSection:(recognizer.view?.tag as Int!)!)
if (indexPath.row == 0) {
for (indexx, bl) in arrayForBool.enumerate() {
if recognizer.view!.tag != indexx {
let index : NSIndexPath = NSIndexPath(forRow: 0, inSection:(indexx))
arrayForBool.replaceObjectAtIndex(index.section, withObject: false)
let range = NSMakeRange(index.section, 1)
let sectionToReload = NSIndexSet(indexesInRange: range)
self.tableList.reloadSections(sectionToReload, withRowAnimation:UITableViewRowAnimation.Fade)
}
}
var collapsed = arrayForBool.objectAtIndex(indexPath.section).boolValue
print_debug(collapsed)
collapsed = !collapsed;
print_debug(collapsed)
arrayForBool.replaceObjectAtIndex(indexPath.section, withObject: collapsed)
print(arrayForBool)
//reload specific section animated
let range = NSMakeRange(indexPath.section, 1)
let sectionToReload = NSIndexSet(indexesInRange: range)
self.tableList.reloadSections(sectionToReload, withRowAnimation:UITableViewRowAnimation.Fade)
rotateSectionIconOnTapped(recognizer.view!.tag)
}
}
get action for didselect row at index path :
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
print_debug(indexPath)
print_debug(indexPath.row)
print_debug(indexPath.section)
if indexPath.section == 0 {
}
else if indexPath.section == 1 {
}
}

How to split text separated with "," on new UITableView custom cell in UITableView

Problem Statement:
I want to display text separated by "," on new custom UITableViewCell.
Problem: It displays all data in single custom cell only with multi-line property, as shown in below.
I want to display tableView like this way.
Now I'm trying to display above data separated by "," on each new custom cell, as shown in above screenshot, but it displays only 1st data and skip remaining data, as per my code.
let Meaning :String = "Aback,Abacus,Abandon,Able,Aboard"
let Smeaning :String = "Fabric,Habit,keen,Pace"
func tableView(tableViewData: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableViewData.dequeueReusableCellWithIdentifier("cell")! as! StudentCell
let fmeaning = Mmeaning.characters.split{$0 == ","}.map(String.init)
let smeaning = Hmeaning.characters.split{$0 == ","}.map(String.init)
for var i = 0; i < fmeaning.count; i += 1{
print(fmeaning[i])
//Here it prints all values perfectly
}
for var i = 0; i < smeaning.count; i += 1{
print(smeaning[i])
//Here it prints all values perfectly
}
Problem occurs here below two statements: display only 1st value in UITableView
cell.lblMeaning1.text = fmeaning[indexPath.row]
cell.lblMeaning2.text = smeaning[indexPath.row]
return cell;
}
How should I assign an Array to these two custom cells, so that it will display data on separate new custom cell?
For that you need to use section table with your tableView, also you need to make this calculation in viewDidLoad and then reload the tableView, For that declare your two instance of array like this in your viewController.
var languageDic = [String: [String]]()
var allLanguage = [String]()
override func viewDidLoad() {
super.viewDidLoad()
let mMeaningArray = Mmeaning.characters.split{$0 == ","}.map(String.init)
let hMeaningArray = Hmeaning.characters.split{$0 == ","}.map(String.init)
self.languageDic = ["Marathi Meaning": mMeaningArray,"Hindi Meaning": hMeaningArray] // You can add other langaue in the dic sam way I have added this two
self.allLanguage = Array(self.languageDic.keys) as [String]
self.tableView.reloadData()
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return self.allLanguage.count
}
func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String {
return self.allLanguage[indexPath.section]
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.languageDic[self.allLanguage[section]].count
}
func tableView(tableViewData: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableViewData.dequeueReusableCellWithIdentifier("cell")! as! StudentCell
let str = self.languageDic[self.allLanguage[indexPath.section]][indexPath.row]
cell.lblMeaning1.text = str
return cell
}
Note: In cellForRowAtIndexPath you need only one label.
Edit: As of you want return the count of array that have more element you can try like this. F
var mMeaningArray = [String]()
var hMeaningArray = [String]()
override func viewDidLoad() {
super.viewDidLoad()
self.mMeaningArray = Mmeaning.characters.split{$0 == ","}.map(String.init)
self.hMeaningArray = Hmeaning.characters.split{$0 == ","}.map(String.init)
self.tableView.reloadData()
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return (self.mMeaningArray.count > self.hMeaningArray.count)? self.mMeaningArray.count : self.hMeaningArray.count
}
func tableView(tableViewData: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableViewData.dequeueReusableCellWithIdentifier("cell")! as! StudentCell
if indexPath.row < self.mMeaningArray.count {
cell.lblMeaning1.text = self.mMeaningArray[indexPath.row]
}
else {
cell.lblMeaning1.text = ""
}
if indexPath.row < self.hMeaningArray.count {
cell.lblMeaning2.text = self.hMeaningArray[indexPath.row]
}
else {
cell.lblMeaning2.text = ""
}
return cell
}
the numberOfRowsInSection() function should return fmeaning.count and smeaning.count... put an if to determine which table you want to have the correct row number.
also you cand display the fmeaning as a section in your tableview, and the smeaning as cells.

TableView's textLabel height according to content

I have made an Collapsed TableView. The size of the tableView's label is not increasing according the content. I had set WordWrap and Lines = 0 but still it's not working.
I'm using 2 tableView cell's to make the collapsed view.
extension UIView {
func rotate(toValue: CGFloat, duration: CFTimeInterval = 0.2, completionDelegate: AnyObject? = nil) {
let rotateAnimation = CABasicAnimation(keyPath: "transform.rotation")
rotateAnimation.toValue = toValue
rotateAnimation.duration = duration
rotateAnimation.removedOnCompletion = false
rotateAnimation.fillMode = kCAFillModeForwards
if let delegate: AnyObject = completionDelegate {
rotateAnimation.delegate = delegate
}
self.layer.addAnimation(rotateAnimation, forKey: nil)
}
}
class CollapsibleTableViewController: UITableViewController {
struct Section {
var name: String!
var items: [String]!
var collapsed: Bool!
init(name: String, items: [String], collapsed: Bool = false) {
self.name = name
self.items = items
self.collapsed = collapsed
}
}
var sections = [Section]()
override func viewDidLoad() {
super.viewDidLoad()
sections = [Section(name: "TEXT OVER HERE", items: ["TEXT OVER HERE."])]
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return sections.count
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return (sections[section].collapsed!) ? 0 : sections[section].items.count
}
override func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let header = tableView.dequeueReusableCellWithIdentifier("header") as! CollapsibleTableViewHeader
header.toggleButton.tag = section
header.titleLabel.text = sections[section].name
header.toggleButton.rotate(sections[section].collapsed! ? 0.0 : CGFloat(M_PI_2))
header.toggleButton.addTarget(self, action: #selector(CollapsibleTableViewController.toggleCollapse), forControlEvents: .TouchUpInside)
return header.contentView
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell") as UITableViewCell!
cell.textLabel?.lineBreakMode = NSLineBreakMode.ByWordWrapping
cell.textLabel?.numberOfLines = 0
cell.textLabel?.text = sections[indexPath.section].items[indexPath.row]
return cell
}
//
// MARK: - Event Handlers
//
func toggleCollapse(sender: UIButton) {
let section = sender.tag
let collapsed = sections[section].collapsed
// Toggle collapse
sections[section].collapsed = !collapsed
// Reload section
tableView.reloadSections(NSIndexSet(index: section), withRowAnimation: .Automatic)
}
}
try this code:
func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
var lblSectionName: UILabel = UILabel()
lblSectionName.text = self.sectionNames[section]
lblSectionName.numberOfLines = 0
lblSectionName.lineBreakMode = .ByWordWrapping
lblSectionName.sizeToFit()
return lblSectionName.frame.size.height
}
func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
var lblSectionName: UILabel = UILabel()
lblSectionName.text = self.sectionNames[section]
lblSectionName.numberOfLines = 0
lblSectionName.lineBreakMode = .ByWordWrapping
lblSectionName.sizeToFit()
return lblSectionName
}
Better is this answer: https://stackoverflow.com/a/29763200/1054550
self.tableView.sectionHeaderHeight = UITableViewAutomaticDimension;
self.tableView.estimatedSectionHeaderHeight = 25;

First grouped table view section header not showing

I have a grouped table view which I want to have customized section headers. But I'm having trouble showing the first section header for the table view.
I have two sections and the section header for the first section is not showing but the second one is:
I have seen similar problems and those problems where solved by implementing the heightForHeaderInSection but I have implemented that.
I'm setting the sections like this:
let kSectionHeaderContact: String = "CONTACT INFORMATION"
let kSectionHeaderFeedback: String = "FEEDBACK"
enum Sections: Int {
case ContactSection = 0
case FeedbackSection = 1
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 2
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == Sections.ContactSection.rawValue {
return contactObjectsDictionary.count
} else if section == Sections.FeedbackSection.rawValue {
return feedbackObjectsDictionary.count
} else {
return 0
}
}
override func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
if section == Sections.ContactSection.rawValue {
sectionHeaderView.sectionHeaderTitle.text = kSectionHeaderContact
} else if section == Sections.FeedbackSection.rawValue {
sectionHeaderView.sectionHeaderTitle.text = kSectionHeaderFeedback
}
return sectionHeaderView
}
override func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return kContactTableViewSectionHeaderViewHeight
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(kCellIdentifierContactTableViewCell, forIndexPath: indexPath) as! ContactTableViewCell
// Configure the cell...
var titleText: String = ""
var detailText: String = ""
if indexPath.section == Sections.ContactSection.rawValue {
let contactObject = contactObjectsDictionary[indexPath.row]
titleText = contactObject[kDictionaryTitleKey]!
detailText = contactObject[kDictionaryDetailKey]!
} else if indexPath.section == Sections.FeedbackSection.rawValue {
let feedbackObject = feedbackObjectsDictionary[indexPath.row]
titleText = feedbackObject[kDictionaryTitleKey]!
detailText = feedbackObject[kDictionaryDetailKey]!
}
cell.configureCell(titleText, detail: detailText)
return cell
}
I'm implementing my custom section header in the storyboard and then referencing it by an outlet:
Edited:
I want to be able to design my custom section header in the storyboard and not programmatically.
Problem is inside viewForHeaderInSection method.
You need to create new instance of UIView & need to return it.
OR
You can create Class for UITableViewHeaderHeaderView and Reuse it.
Feel free to ask if you have any doubts regarding this.
let titleFirstLabel: UILabel = {
let label = UILabel()
label.text = "Text"
label.frame = CGRect(x: 15, y: 10, width: 100, height: 20)
return label
}()
and viewDidLoad() add this code
tableView.addSubview(titleFirstLabel)
That work for me. Good luck :)

Resources