Search code examples
swifttableviewxib

How to switch custom xib cell when didSelect call?


I have a tableView with 2 custom xib cells. I want to switch the custom cell when user tapped it also adjust the cell height. How do I achieve it? I tried to use container view but then the height would be the same. I want to know if it is possible to do it with two xib for tableView cell? Thank you.

var isContactView: Bool = true

override func viewDidLoad() {
    super.viewDidLoad()

    tableView.delegate = self
    tableView.dataSource = self
    tableView.register(UINib(nibName: "ContactTableViewCell", bundle: nil), forCellReuseIdentifier: "contactCell")
    tableView.register(UINib(nibName: "DetailTableViewCell", bundle: nil), forCellReuseIdentifier: "detailCell")
}

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    //if ContactTableViewCell return 40
    //if DetailTableViewCell return 150
}

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

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    //by default the cell view is ContactTableViewCell. 
    //When user tapped the cell it will change to DetailTableViewCell.
    if isContactView {
        let cell = tableView.dequeueReusableCell(withIdentifier: "contactCell", for: indexPath) as! ContactTableViewCell
        //do something...
    } else {
        let cell = tableView.dequeueReusableCell(withIdentifier: "detailCell", for: indexPath) as! DetailTableViewCell
        //do something...
    }

    return cell
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    //not sure how to change the xib in here.
    
    //if cell view is ContactTableViewCell 
        cell view = tableView.dequeueReusableCell(withIdentifier: "detailCell", for: indexPath) as! DetailTableViewCell
        isContactView = false
        tableView.reloadData()
    
    //else 
        cell view = tableView.dequeueReusableCell(withIdentifier: "contactCell", for: indexPath) as! ContactTableViewCell
        isContactView = true
        tableView.reloadData()
}

Solution

  • There are 2 cases:

    1. If there's just single cell to be viewed, then just put the following code in didSelect:

    isContactView = !isContactView

    tableView.reloadData()

    1. If there are multiple cells in which the condition is to be applied. Please put a key in your data model.

    For example:

    testArr is the array of objects that you are displaying in tableview. Then keep a key, say isContactView in this model. And put the login based upon this key.

    Like in case of cellForRow:

    if testArr[indexpath.row].isContactView {
            let cell = tableView.dequeueReusableCell(withIdentifier: "contactCell", for: indexPath) as! ContactTableViewCell
            //do something...
    } else {
            let cell = tableView.dequeueReusableCell(withIdentifier: "detailCell", for: indexPath) as! DetailTableViewCell
            //do something...
    }
    

    And in didselect:

    isContactView = !testArr[indexPath.row].isContactView