表视图在索引路径问题

时间:2018-04-09 06:46:09

标签: ios swift uitableview

Apple doc说:reloadRowsAtIndexPaths:withRowAnimation: :

  

如果要提醒用户单元格的值正在更改,请调用此方法。但是,如果通知用户并不重要 - 也就是说,您只想更改单元格显示的值 - 您可以获取特定行的单元格并设置其新值。

我的问题场景是我想在按钮点击时更新单元格中的标签,并且还更新布局(即在应用的条件下添加或删除单元格的新视图)。如果在按钮上单击调用reloadRowsAtindexPath,则tableview会随机向下滚动到tableview中的其他行。如果仅在按钮单击时更新单元格内容,则布局未正确更新。

如果有人在重装时遇到同样的问题吗?

2 个答案:

答案 0 :(得分:2)

这比我想象的要复杂得多。

以下是我实施它的方式。我不确定这是不是一个好方法,所以拿一粒盐。找到下面项目的链接。

你需要知道两件事:

  
      
  1. 默认/正常单元格高度(基本上是单元格的估计高度)。
  2.   
  3. 将视图添加到单元格后,单元格的高度增加(在我的示例中,我将高度设置为200)。
  4.   

当你点击一个应该添加子视图的按钮时,你会调用一个完成处理程序,将indexPathheightToBeAdded(本例中为200)作为参数传递。

完成将如下所示:

self.indexPath = iPath
self.cellHeight = self.defaultCellHeight + heightToBeAdded
UIView.beginAnimations("aaa", context: nil)
UIView.setAnimationDuration(1)
self.tableView.beginUpdates()
self.tableView.reloadRows(at: [iPath], with: .none)
self.tableView.endUpdates()
UIView.commitAnimations()
if heightToBeAdded > 0.0 {
    self.addCellSubviews()
}

iPath与您发送参数的indexPath相同。细胞高度是根据我上面描述的两件事来计算的。

endUpdates()调用委托时,数据源方法会遇到以下方法:

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    guard let iPath = self.indexPath else { return UITableViewAutomaticDimension }
    if indexPath == iPath {
        return cellHeight
    }
    else {
        return UITableViewAutomaticDimension
    }
}

这会增加细胞高度。但是需要添加的实际子视图呢?

为此,我们有addCellSubviews(),它实际上是在UITableViewCell子类内执行的完成块。仅在结束更新后调用此方法,因为此时将正确计算单元格高度。

let yView = UIView()
yView.backgroundColor = .yellow
yView.translatesAutoresizingMaskIntoConstraints = false
self.addAsSubview(sView: yView)
NSLayoutConstraint.activate([
        yView.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 8),
        yView.topAnchor.constraint(equalTo: self.topAnchor, constant: 8),
        yView.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -275),
        yView.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -8)
        ])
UIView.animate(withDuration: 1, animations: {
        self.layoutIfNeeded()
})

结果如下 - enter image description here

Link to the project

请注意有一些警告(比如轻敲一个单元格关闭另一个单元格),我相信你能够解决这个问题。

答案 1 :(得分:0)

这是估计行高的问题。将值更改为其他估计值可修复不需要的滚动问题。

苹果文档中提到:"此外,尽量使估计的行高尽可能准确。系统根据这些估计值计算滚动条高度等项目。估算越准确,用户体验就越无缝。"