swiftuitableviewuikittable-footer

SWIFT / UIKit Footer text displaying over dynamic tableViewCell


enter image description here

I have a UITableViewcontroller setup with just two cells. The footer text is displaying over the last cell.

Strangely I have other controllers with practically the same setup and code and where the footer is showing as expected.

I have tried tried changing the style group / inset etc.

Any ideas appreciated. Thanks

import UIKit

class LanguagesTableViewController: UITableViewController {

    var checked = [Bool]()
    var choices = ["English","French"]
    
    
    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.allowsMultipleSelection = false
        
        let defaults = UserDefaults.standard
        checked = defaults.array(forKey: "Language")  as? [Bool] ?? [true, false]
        
    }
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        
        updateSwitchState()
        
        tableView.reloadData()
        
    }
    
    // MARK: - Table view data source

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        let cell = tableView.dequeueReusableCell(withIdentifier: "languageChoiceCell", for: indexPath)
        
        cell.textLabel?.text = choices[indexPath.row]
        
        if !checked[indexPath.row] {
                cell.accessoryType = .none
            } else if checked[indexPath.row] {
                cell.accessoryType = .checkmark
            }
        
        return cell
    }

    override func numberOfSections(in tableView: UITableView) -> Int {
        // #warning Incomplete implementation, return the number of sections
        return 1
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // #warning Incomplete implementation, return the number of rows
        return choices.count
    }

    override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        
        if checked[indexPath.row] {

            tableView.selectRow(at: indexPath, animated: false, scrollPosition: UITableView.ScrollPosition.none)
            
        }

    }
    
    override func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? {

        return Constants.languagesFooterText
    }
    

    
    
    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

        // If we are selecting a row that is already checked we do nothing

        guard !checked[indexPath.row] else { return }

        // Reset all checked state.

        checked = [Bool](repeating: false, count: choices.count)

        // And set the current row to true.

        checked[indexPath.row] = true

        if let cell = tableView.cellForRow(at: indexPath) {
                if cell.accessoryType == .checkmark {
                     cell.accessoryType = .none
                     checked[indexPath.row] = false
                } else {
                     cell.accessoryType = .checkmark
                     checked[indexPath.row] = true
                }
            }

        updateSwitchState()

    }
    
    // did ** DE ** Select
    
    override func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {

        if let cell = tableView.cellForRow(at: indexPath) {
                if cell.accessoryType == .checkmark {
                     cell.accessoryType = .none
                     checked[indexPath.row] = false
                } else {
                     cell.accessoryType = .checkmark
                     checked[indexPath.row] = true
                }
            }

        updateSwitchState()

    }
    
    func updateSwitchState() {
        
        let defaults = UserDefaults.standard
        defaults.set(checked, forKey: "Language")
        
    }
   
}

enter image description here


Solution

  • You should set a height on your footer view. You can do this by calling tableView(:heightForFooterInSection:) and returning UITableView.automaticDimension.

    As you are inheriting from UITableViewController you can do it in the following way

    override func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
        UITableView.automaticDimension
    }
    

    This will give you the following result:

    UITableView with a footer that has a dynamic height