Custom UITableViewCell height changes when moved

你说的曾经没有我的故事 提交于 2019-12-24 07:25:13

问题


I am using Autolayout and estimatedHeightForRowAtto dynamically change cell height. This is the code I am using:

var heightAtIndexPath = NSMutableDictionary()

func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
    let height = self.heightAtIndexPath.object(forKey: indexPath)
    if ((height) != nil) {
        return CGFloat(height as! CGFloat)
    } else {
        return UITableViewAutomaticDimension
    }
}

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    let height = cell.frame.size.height
    self.heightAtIndexPath.setObject(height, forKey: indexPath as NSCopying)
}

In viewDidLoad()

tableView.rowHeight = UITableViewAutomaticDimension
tableView.reloadData()

Now when I do a swipe right to 'complete a task', the priorityNumberon which the data is sorted becomes 0 for that particular cell and the cell moves to the bottom of the list. I am using NSFetchedResultsController changeType .move to move the cell to the bottom automatically when the coreData is changed.

The issue is that the cell changes it's height a bit when moved. It's random - sometimes it changes when it goes to the '0th' position and sometimes it changes when it goes back to it's original position.

It doesn't happen always, but sometimes. Any idea what maybe the issue. Here is the autolayout constraints for the contents in the custom cell:

textview.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 48).isActive = true
    textview.topAnchor.constraint(equalTo: contentView.topAnchor,  constant: 6).isActive = true
    textview.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -8).isActive = true
    textview.bottomAnchor.constraint(equalTo: scheduledSign.topAnchor, constant: -2).isActive = true
   // textview.bottomAnchor.constraint(equalTo: line.topAnchor, constant: 0).isActive = true

    _ = scheduledSign.anchor(nil, left: contentView.leftAnchor, bottom: line.topAnchor, right: contentView.rightAnchor, topConstant: 2, leftConstant: 54, bottomConstant: 4, rightConstant: 8, widthConstant: 0, heightConstant: 0)

    line.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 48).isActive = true
    line.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: 0).isActive = true
    line.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: 0).isActive = true
   // line.topAnchor.constraint(equalTo: textview.bottomAnchor, constant: 0).isActive = true
    line.heightAnchor.constraint(equalToConstant: 0.5).isActive = true

   _ = prioritycircle.anchor(self.contentView.topAnchor, left: self.contentView.leftAnchor, bottom: nil, right: nil, topConstant: 20, leftConstant: 16, bottomConstant: 0, rightConstant: 8, widthConstant: 20  , heightConstant: 20)

Here is a video of this issue: https://youtu.be/ecU3_ticw3g

Please help! Thanks.

This is my cellforrowatindexPath

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: cellid, for: indexPath) as! TasksTableViewCell

    cell.textview.text = fetchedResultsController.object(at: indexPath).sNote
    cell.prioritycircle.backgroundColor = fetchedResultsController.object(at: indexPath).sPriorityColor
    cell.selectionStyle = UITableViewCellSelectionStyle.none
    cell.backgroundColor = fetchedResultsController.object(at: indexPath).cellbackgroundColor
    cell.textview.backgroundColor = fetchedResultsController.object(at: indexPath).cellbackgroundColor
    cell.belliconview.tintColor = fetchedResultsController.object(at: indexPath).belliconcolor
   // cell.scheduledSign.backgroundColor = fetchedResultsController.object(at: indexPath).cellbackgroundColor
    if (fetchedResultsController.object(at: indexPath).sTaskCompleted)
    {
        cell.isUserInteractionEnabled = false
    }
    else{
        cell.isUserInteractionEnabled = true
    }

    if (fetchedResultsController.object(at: indexPath).sReminderState) {

        cell.belliconview.tintColor = (fetchedResultsController.object(at: indexPath).belliconcolor)
        //cell.scheduledSign.text = fetchedResultsController.object(at: indexPath).sReminderDate
    } else {
        cell.belliconview.tintColor = (fetchedResultsController.object(at: indexPath).belliconcolor) 
    }

    cell.layer.shouldRasterize = true
    cell.layer.rasterizationScale = UIScreen.main.scale

    return cell
}

and this is where I am reloading my tableview after content change in FRC:

 func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
    switch type {

    case .delete:
        tableView.deleteRows(at: [indexPath!], with: .fade)
    case .insert:
        tableView.insertRows(at: [newIndexPath!], with: UITableViewRowAnimation.automatic)
    case .move:
        tableView.deleteRows(at: [indexPath!], with: .fade)
        tableView.insertRows(at: [newIndexPath!], with: .fade)

    case .update:
        tableView.reloadRows(at: [indexPath!], with: .fade)

    default:
        return

    }
}

回答1:


Simple Logic. Try to use UILabel instead of UITextView once.

Add UILabel in UITableViewCell (Row height = 44) . Give constraints, "5,5,5,5" and height as "34". Number of lines as Zero. In Size Inspector, Give horizontal and vertical as 1000 & 1000 respectively for both Content Hugging Property and Content Compression Resistance Priority.

Click, UILabel's Height Constraints, in Size Inspector, Change its Priority to 750.

let getValuesInString = ["abc\nLets meet today\nyes. sure", "123", "qwerty\n12345\nASDD\n123"]

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

        return getValuesInString.count 
    }
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! SampleTableViewCell
        cell.testLbl.text = getValuesInString[indexPath.row]
        cell.selectionStyle = .none
        return cell
    }

 func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {

    return 50
}

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {

    return UITableViewAutomaticDimension 

}

Storyboard Constraints



来源:https://stackoverflow.com/questions/48479246/custom-uitableviewcell-height-changes-when-moved

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