Swift 3 - Expandable Table View Cells with first cell already expanded
Solution 1
I feel like you do not fully understand your own code but since you did put a lot of effort into your question I will give you a hint.
In your UITableViewController somewhere at the top you initialise selectedIndexPath which should look something like
var selectedIndexPath: IndexPath?
You can set that to a default value like this
var selectedIndexPath: IndexPath? = IndexPath(row: 0, section: 0)
So cell at (row: 0, section: 0) will expand on default.
Solution 2
Yesterday I have completed similar feature with reference to this sample: https://github.com/justinmfischer/SwiftyAccordionCells
As per your implementation, you are tracking the current expanded cell using "selectedIndexPath". So when your view is loaded you have to set "selectedIndexPath" row and section value to 0 as you are using only one section.
Hope this is helpful!
Solution 3
In viewDidLoad
set selectedIndexPath = IndexPath(row: 0, section: 0)
That should "auto-expand" the first row.
noblerare
Updated on June 05, 2022Comments
-
noblerare almost 2 years
I am using Swift 3.
I've followed this tutorial to get it so that I can tap on a table view cell which will expand revealing more information.
https://www.youtube.com/watch?v=VWgr_wNtGPM&t=294s
My question is: how do I do it so that the first cell is expanded when the view loads already (i.e. the user doesn't have to click to see that cell expand) but all other behavior remains the same (e.g. if it's clicked again, it de-collapses)?
UITableViewCell
:import UIKit class ResultsCell: UITableViewCell { @IBOutlet weak var introPara : UITextView! @IBOutlet weak var section_heading : UILabel! class var expandedHeight : CGFloat { get { return 200.0 } } class var defaultHeight : CGFloat { get { return 44.0 } } var frameAdded = false required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) } override func awakeFromNib() { super.awakeFromNib() section_heading.translatesAutoresizingMaskIntoConstraints = false } func checkHeight() { introPara.isHidden = (frame.size.height < ResultsCell.expandedHeight) } func watchFrameChanges() { if(!frameAdded) { addObserver(self, forKeyPath: "frame", options: .new, context: nil) checkHeight() } } func ignoreFrameChanges() { if(frameAdded){ removeObserver(self, forKeyPath: "frame") } } deinit { print("deinit called"); ignoreFrameChanges() } // when our frame changes, check if the frame height is appropriate and make it smaller or bigger depending override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { if keyPath == "frame" { checkHeight() } } }
UITableViewController
// class declaration and other methods above here... override func numberOfSections(in tableView: UITableView) -> Int { return 1 } // number of rows in the table view override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return section_heading.count } // return the actual view for the cell override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let resultcell = tableView.dequeueReusableCell(withIdentifier: "resultCellTemplate", for: indexPath) as! ResultsCell resultcell.section_heading.text = section_heading[indexPath.row] resultcell.introPara.attributedText = contentParagraphs[indexPath.row] return resultcell } // when a cell is clicked override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { let previousIndexPath = selectedIndexPath // the row is already selected, then we want to collapse the cell if indexPath == selectedIndexPath { selectedIndexPath = nil } else { // otherwise, we expand that cell selectedIndexPath = indexPath } var indexPaths : Array<IndexPath> = [] // only add a previous one if it exists if let previous = previousIndexPath { indexPaths.append(previous) } if let current = selectedIndexPath { indexPaths.append(current) } // reload the specific rows if indexPaths.count > 0 { tableView.reloadRows(at: indexPaths, with: .automatic) } } override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { (cell as! ResultsCell).watchFrameChanges() } override func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) { (cell as! ResultsCell).ignoreFrameChanges() } override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { if indexPath == selectedIndexPath { return ResultsCell.expandedHeight } else { return ResultsCell.defaultHeight } }
So this works as intended.
But how do I make it so that the first cell is already expanded?
Thanks for your help.