Search code examples
swiftuitableviewfooter

How to create dynamic TableView footer by changing height of cells


I want to create a footer which is dynamic to the height of the tableview cells.

My initial situation looks like:

enter image description here

If I click on a row, it change the height of this cell to 194 (44 before)

enter image description here

It don't show all rows.

If I get the footer -150 it looks like:

enter image description here

And if I close all cells it looks like and the 150 which I get to footer with -150 are white here:

enter image description here

My code:

var selectedCellIndexPath: Int?
let selectedCellHeight: CGFloat = 194.0
let unselectedCellHeight: CGFloat = 44.0
var cellsHeight = [44, 44, 44]

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    tableView.beginUpdates()
    if selectedCellIndexPath != nil && selectedCellIndexPath == indexPath.row {
        selectedCellIndexPath = nil
    }
    else {
        selectedCellIndexPath = indexPath.row
    }
    if selectedCellIndexPath != nil {
        tableView.scrollToRow(at: indexPath, at: .none, animated: true)
    }
    tableView.endUpdates()
}

func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
    let rowHeight:CGFloat = 44
    var rowsHeight:CGFloat = 3 * rowHeight
    /*for i in 0..<cellsHeight.count {
        rowsHeight += CGFloat(cellsHeight[i])
    }*/
    let topHeight = UIApplication.shared.statusBarFrame.height + self.navigationController!.navigationBar.frame.height
    let viewHeight = self.view.frame.height
    let headerHeight:CGFloat = 30
    let height = viewHeight - topHeight - rowsHeight - headerHeight //- 150

    return CGFloat(height)
}

Only one row will have the height 194 and the other 44. Any ideas how to solve the problem? Thx

Edit:

func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return 3
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let dateFormatter = DateFormatter()
    //dateFormatter.dateStyle = DateFormatter.Style.short
    dateFormatter.dateFormat = "dd.MM.yyyy HH:mm"

    if indexPath.row == 0 {
        let cell = tableView.dequeueReusableCell(withIdentifier: "workoutDateCell", for: indexPath) as! WorkoutDateTableViewCell
        cell.typeLabel.text = "Beginn"
        cell.dateDatepicker.date = Date()
        cell.dateDatepicker.tag = indexPath.row
        cell.dateLabel.text = dateFormatter.string(from: cell.dateDatepicker.date)
        cell.selectionStyle = .none
        return cell
    }
    else if indexPath.row == 1 {
        let cell = tableView.dequeueReusableCell(withIdentifier: "workoutDateCell", for: indexPath) as! WorkoutDateTableViewCell
        cell.typeLabel.text = "Ende"
        cell.dateDatepicker.date = Date()
        cell.dateDatepicker.tag = indexPath.row
        cell.dateLabel.text = dateFormatter.string(from: cell.dateDatepicker.date)
        cell.selectionStyle = .none
        return cell
    }
    else {
        let cell = tableView.dequeueReusableCell(withIdentifier: "workoutSportsCell", for: indexPath) as! WorkoutSportsTableViewCell
        cell.sportsLabel.text = "Sportart"
        cell.sportstypeLabel.text = workoutSports[coreData.getSportsIndex()]
        cell.sportsPicker.delegate = self
        cell.sportsPicker.dataSource = self
        cell.sportsPicker.selectRow(coreData.getSportsIndex(), inComponent: 0, animated: false)
        cell.selectionStyle = .none
        return cell
    }
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    if selectedCellIndexPath == indexPath.row {
        return selectedCellHeight
    }
    return unselectedCellHeight
}

Solution

  • To archive this you can use only cells instead of footer view.

    Step 1: Remove Footer View.

    Step 2: Add Cell of Date Picker.

    Step 3: When you click on Begin & End DateTime cell, then insert DateTime cell below selected cell and reload table view.

    Step 4: Hope that will resolve your problem.

    Let me know if you have any query.

    Edit: As per discuss you only need to remove the extra cell separator by using tableFooterViewForSection.

    So you only need to add below line to solve your problem:

    tableView.tableFooterView = UIView(frame: CGRect(x:0, y:0, width:tableView.frame.width, heigth:0))
    

    And Remove func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat method.

    Hope it will help you.