I'm able to expand and collapse cells but i wanna call functions (expand and collapse) inside UITableViewCell to change button title.
import UIKit class MyTicketsTableViewController: UITableViewController { var selectedIndexPath: NSIndexPath? var extraHeight: CGFloat = 100 override func viewDidLoad() { super.viewDidLoad() } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 5 } override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! MyTicketsTableViewCell return cell } override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { if(selectedIndexPath != nil && indexPath.compare(selectedIndexPath!) == NSComparisonResult.OrderedSame) { return 230 + extraHeight } return 230.0 } override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { if(selectedIndexPath == indexPath) { selectedIndexPath = nil } else { selectedIndexPath = indexPath } tableView.beginUpdates() tableView.endUpdates() } }
import UIKit class MyTicketsTableViewCell: UITableViewCell { @IBOutlet weak var expandButton: ExpandButton! @IBOutlet weak var detailsHeightConstraint: NSLayoutConstraint! var defaultHeight: CGFloat! override func awakeFromNib() { super.awakeFromNib() defaultHeight = detailsHeightConstraint.constant expandButton.button.setTitle("TAP FOR DETAILS", forState: .Normal) detailsHeightConstraint.constant = 30 } func expand() { UIView.animateWithDuration(0.3, delay: 0.0, options: .CurveLinear, animations: { self.expandButton.arrowImage.transform = CGAffineTransformMakeRotation(CGFloat(M_PI * 0.99)) self.detailsHeightConstraint.constant = self.defaultHeight self.layoutIfNeeded() }, completion: { finished in self.expandButton.button.setTitle("CLOSE", forState: .Normal) }) } func collapse() { UIView.animateWithDuration(0.3, delay: 0.0, options: .CurveLinear, animations: { self.expandButton.arrowImage.transform = CGAffineTransformMakeRotation(CGFloat(M_PI * 0.0)) self.detailsHeightConstraint.constant = CGFloat(30.0) self.layoutIfNeeded() }, completion: { finished in self.expandButton.button.setTitle("TAP FOR DETAILS", forState: .Normal) }) } }
Table views in iOS display rows of vertically scrolling content in a single column. Each row in the table contains one piece of your app's content. For example, the Contacts app displays the name of each contact in a separate row, and the main page of the Settings app displays the available groups of settings.
If you want the cell to get physically bigger, then where you have your store IndexPath
, in heightForRow:
use:
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { if selectedIndexPath == indexPath { return 230 + extraHeight } return 230.0 }
Then when you want to expand one in the didSelectRow:
selectedIndexPath = indexPath tableView.beginUpdates tableView.endUpdates
Edit
This will make the cells animate themselves getting bigger, you dont need the extra animation blocks in the cell.
Edit 2
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { if(selectedIndexPath == indexPath) { selectedIndexPath = nil if let cell = tableView.cellForRowAtIndexPath(indexPath) as? MyTicketsTableViewCell { cell.collapse() } if let cell = tableView.cellForRowAtIndexPath(NSIndexPath(forRow:indexPath.row+1, section: indexPath.section) as? MyTicketsTableViewCell { cell.collapse() } } else { selectedIndexPath = indexPath if let cell = tableView.cellForRowAtIndexPath(indexPath) as? MyTicketsTableViewCell { cell.expand() } if let cell = tableView.cellForRowAtIndexPath(NSIndexPath(forRow:indexPath.row+1, section: indexPath.section) as? MyTicketsTableViewCell { cell.expand() } } tableView.beginUpdates() tableView.endUpdates() }
All you need is implement UITableView
Delegate this way:
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { return UITableViewAutomaticDimension } override func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { return UITableViewAutomaticDimension }
By default, estimatedHeight
is CGRectZero
, when you set some value for it, it enables autoresizing (the same situation with UICollectionView
), you can do even also so:
tableView?.estimatedRowHeight = CGSizeMake(50.f, 50.f);
Then you need to setup you constraints inside your cell.
Check this post: https://www.hackingwithswift.com/read/32/2/automatically-resizing-uitableviewcells-with-dynamic-type-and-ns
Hope it helps)
In MyTicketsTableViewController
class, inside cellForRowAtIndexPath
datasource method add target for the button.
cell.expandButton.addTarget(self, action: "expandorcollapsed:", forControlEvents: UIControlEvents.TouchUpInside)
I tried to implement lots of the given examples on this and other pages with similar questions, but none worked for me since I had to perform some logic in my custom cell (eg. hide unneeded UILables in CustomCell.swift when the cell is collapsed).
Here is the implementation that worked for me:
Create a dictionary:
private var _expandedCells: [IndexPath:Bool] = [:]
Implement the heightForRowAt method:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return _expandedCells[indexPath] == nil ? 70 : _expandedCells[indexPath]! ? 150 : 70
}
Implement the didSelectRowAt method:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
_expandedCells[indexPath] = _expandedCells[indexPath] == nil ? true : !_expandedCells[indexPath]!
tableView.reloadRows(at: [indexPath], with: .fade)
}
Adjust your customCell:
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
guard let cell = cell as? YourCustomTableViewCell, let isExpanded = _expandedCells[indexPath] else { return }
cell.set(expanded: isExpanded)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With