swift: How to Flip Cell between two UITableViewCell

限于喜欢 提交于 2019-12-13 03:38:57

问题


I have two UITableViewCell in a UITableViewController.

I want to flip indexPaths on click didSelect method.

When I will click indextPath.row “0” in tableViewCellOne it will show indexPath.row “0” of tableViewCellTwo.

Now it is not flip properly. Also crash apps after click a few time on didSelect method.

Error message is:

//Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Attempted to dequeue multiple cells for the same index path, which is not allowed. If you really need to dequeue more cells than the table view is requesting, use the -dequeueReusableCellWithIdentifier: method (without an index path). Cell identifier: FlipTableViewCellZero, index path:

var isOpen = true

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    if isOpen{

        let cell = tableView.dequeueReusableCell(withIdentifier: "FlipTableViewCellZero", for: indexPath) as! FlipTableViewCellZero

        var categoryObject = arrNewsList[indexPath.section]

        cell.profileImage = categoryObject[indexPath.row].textView
        return cell

    }else{

        let cell = tableView.dequeueReusableCell(withIdentifier: "FlipTableViewCellOne", for: indexPath) as! FlipTableViewCellOne

        var categoryObject = arrNewsList[indexPath.section]

        cell.newsTextView.text = categoryObject[indexPath.row].details

        return cell

    }
    return tableView.dequeueReusableCell(withIdentifier: "FlipTableViewCellZero", for: indexPath)

}


func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    isOpen = true

    let selectedCell = tableView.dequeueReusableCell(withIdentifier: "FlipTableViewCellOne", for: indexPath) as! FlipTableViewCellOne
    UIView.transition(with: selectedCell, duration: 0.6, options: .transitionFlipFromLeft, animations: nil, completion: nil)
}

func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
    isOpen = false

    let deselectedCell = tableView.dequeueReusableCell(withIdentifier: "FlipTableViewCellZero", for: indexPath) as! FlipTableViewCellZero
    UIView.transition(with: deselectedCell, duration: 0.6, options: .transitionFlipFromLeft, animations: nil, completion: nil)
}

回答1:


It looks like you want to display your category in two different ways: open and closed.

You're running into problems because you are trying to update the display by dequeueing a new cell in didSelectRowAt and didDeselectRowAt. This is incorrect.

The proper way to update the display is to call either:

  • tableView.reloadData, which reloads the entire table view, or
  • tableView.reloadRows(at:with:), which reloads just the specified rows

For simplicity, I'm going to use the first option in this example.

Another problem with your code is that you are trying to use a class-level variable isOpen to remember the state of your category. This isn't going to work when you have more than one category.

A better approach is to add isOpen as a property of your categoryObject class. You set it initially to false and then toggle it when the row is tapped. Here is a possible solution:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let categoryObject = arrNewsList[indexPath.section]

    if categoryObject.isOpen {
        let cell = tableView.dequeueReusableCell(withIdentifier: "FlipTableViewCellZero", for: indexPath) as! FlipTableViewCellZero

        cell.profileImage = categoryObject[indexPath.row].textView
        return cell
    }
    else {
        let cell = tableView.dequeueReusableCell(withIdentifier: "FlipTableViewCellOne", for: indexPath) as! FlipTableViewCellOne

        cell.newsTextView.text = categoryObject[indexPath.row].details
        return cell
    }
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {    
    let categoryObject = arrNewsList[indexPath.section]
    categoryObject.isOpen = true
    tableView.reloadData()
}

func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
    let categoryObject = arrNewsList[indexPath.section]
    categoryObject.isOpen = false
    tableView.reloadData()
}

Now, this doesn't give you the animation you wanted, but it addresses the core problem with your current code.

To do the animation, check into the documentation for reloadRows(at:with:). Using this method, instead of reloadData(), you can animate the change in display of your category.



来源:https://stackoverflow.com/questions/48720442/swift-how-to-flip-cell-between-two-uitableviewcell

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!