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