【问题标题】:Custom UITableViewCell height changes when moved移动时自定义 UITableViewCell 高度变化
【发布时间】:2018-07-06 20:22:42
【问题描述】:

我正在使用 Autolayout 和 estimatedHeightForRowAt 来动态更改单元格高度。这是我正在使用的代码:

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)
}

viewDidLoad()

tableView.rowHeight = UITableViewAutomaticDimension
tableView.reloadData()

现在,当我向右滑动以“完成任务”时,对数据进行排序的priorityNumber对于该特定单元格变为 0,并且该单元格移动到列表的底部。我正在使用NSFetchedResultsController changeType .move 在更改 coreData 时自动将单元格移动到底部。

问题是单元格在移动时会稍微改变它的高度。它是随机的 - 有时它会在它到达“0th”位置时发生变化,有时它会在它回到原来的位置时发生变化。

它并不总是发生,但有时会发生。任何想法可能是什么问题。这是自定义单元格中内容的自动布局约束:

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)

这里是这个问题的视频:https://youtu.be/ecU3_ticw3g

请帮忙!谢谢。

这是我的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
}

这是我在 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

    }
}

【问题讨论】:

  • 只有可解决的问题。你能显示你的 cellForRowAtIndexPath 代码吗?并且,你在 NSFetchResultController 的帮助下重新加载 tableview
  • @McDonal_11 刚刚用相关代码更新了我的帖子。请看一看。
  • 我会检查并让你
  • 我用过 UILabel。试试这个方法。

标签: ios swift uitableview autolayout cell


【解决方案1】:

简单的逻辑。尝试使用UILabel 而不是UITextView 一次。

在 UITableViewCell (Row height = 44) 中添加 UILabel。给定约束,“5,5,5,5”和高度为“34”。 Number of lines 为零。在Size Inspector 中,将horizontalvertical 分别作为10001000 用于Content Hugging PropertyContent Compression Resistance Priority

单击,UILabel 的高度约束,在Size Inspector 中,将其Priority 更改为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 

}

故事板约束

【讨论】:

  • 会试试这个谢谢。任何想法如何在没有情节提要的情况下做上述事情。具体来说,内容拥抱和优先级等?
  • 没有情节提要,你必须得到 NSDictionary 中的每一行高度。之后,您必须重新加载 tableview。否则,高度会发生变化。原因是,Cell 每次都在重复使用。
  • 好吧,我在没有使用情节提要的情况下完成了整个项目,并且无法恢复。我现在该怎么办?
  • 故事板是最好的。如果你从一开始就在故事板中做,这将需要 1 小时。就是这样。
  • 否则,你必须计算高度并存储在 NSDictionary 中,然后你必须在 heightForRowAtIndexPath 中做。不是,在估计的HeightForRowAt 中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多