This is what I currently have
This is the code extending UITableViewDelegate
extension IngredientsViewController: UITableViewDelegate {
func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 50
}
func tableView(tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 0
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
if self.collapses[indexPath.section] == true {
return 0
}
return 50
}
func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerView = UIView(frame: CGRectMake(0, 0, tableView.frame.size.width, 50))
headerView.backgroundColor = UIColor(hexString: AppConfiguration.UIColorCode["orange"]!, alpha: 0.7)
headerView.tag = section
let headerString = UILabel(frame: CGRect(x: 12, y: 0, width: tableView.frame.size.width-24, height: 50)) as UILabel
headerString.text = (self.stores[section] as! Store).name!.uppercaseString
headerString.textColor = UIColor.whiteColor()
headerString.font = FontCollection.tableHeaderFont
headerView .addSubview(headerString)
let headerTapped = UITapGestureRecognizer (target: self, action:"sectionHeaderTapped:")
headerView .addGestureRecognizer(headerTapped)
return headerView
}
func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
if self.deselecting {
self.deselecting = false
return
}
if self.selectedIndexPath.indexOf(indexPath) != nil {
cell.selected = true
}
}
func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) {
self.selectedIndexPath.removeAtIndex(self.selectedIndexPath.indexOf(indexPath)!)
self.deselecting = true
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
self.selectedIndexPath.append(indexPath)
}
func sectionHeaderTapped(recognizer: UITapGestureRecognizer) {
let indexPath : NSIndexPath = NSIndexPath(forRow: 0, inSection:(recognizer.view?.tag as Int!)!)
if (indexPath.row == 0) {
self.collapses[indexPath.section] = !self.collapses[indexPath.section]
//reload specific section animated
let range = NSMakeRange(indexPath.section, 1)
let sectionToReload = NSIndexSet(indexesInRange: range)
self.tableView.reloadSections(sectionToReload, withRowAnimation: .Fade)
}
}
}
My questions
- The animation feels like each of the cell is fading in/out by itself. I'd rather have the whole section slide up/down. Been looking around but doesn't find much example of this. And I don't understand why the section header is having the white highlight on touch?
- To maintain the selected between collapsing and expanding, I'm storing the selection in an array and use
willDisplayCell
to determine the selection state upon rendering the cell. Is this the right and most efficient approach? Using the above code, when a cell is selected, collapse the section that cell belongs to, expand that section, then the said cell become unresponsive to didSelect and didDeselect (while unselected cells are still responsive). Any ideas why?Update for this issue below.
Thank you.
------ UPDATE ------
The above approach I used for rendering selected state with collapsed cell is flawed (issue #3). The below code will make the cell not interactive anymore
func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
if self.deselecting {
self.deselecting = false
return
}
if self.selectedIndexPath.indexOf(indexPath) != nil {
cell.selected = true
}
}
Instead of that, one should do this
func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
if self.selectedIndexPath.indexOf(indexPath) != nil {
tableView.selectRowAtIndexPath(indexPath, animated: false, scrollPosition: .None)
}
}