Search code examples
iosswiftuitableviewuipickerviewcustom-cell

Expand TableViewCell without using an extra cell


I am using a UITableView with custom cells. Each cell has its own nib file and a controller. In one cell I want to enable user to select a date. A default date is shown on the cell. When the user clicks on the cell a UIPickerView should expand on the cell. I found multiple similar questions on the forum but all of them use an extra cell that contains the UIPickerView. In my app I need to use one nib file that contains both the label and the Pickerview. Maybe when the cell is clicked I should show the pickerView and update the cell height and when the cell is clicked again I should hide it and update the height again. I saw an example somewhere but it was written in Objective-C. Do you think it's possible to implement it in this way and is there a Swift example?


Solution

  • Well, to solve that problem you simply need to setup fixed vertical spacing between label and picker in your cell view. See this screenshot

    fixed vertical spacing

    Then each time user taps on cell you simply reload table view with updated height for cell. Here is the source code:

    class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    
    @IBOutlet weak var tableView: UITableView!
    
    fileprivate var cellExpanded = false
    
    // MARK: - UITableView datasource & delegate
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 1
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "PickerCell")!
    
        return cell
    }
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return (cellExpanded) ? 260:44
    }
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        cellExpanded = !cellExpanded
        tableView.reloadData()
    }
    }