正如这个问题的标题中提到:有什么之间的"差异cellForRowAtIndexPath"和" willDisplayCell:forRowAtIndexPath?:"`
我认为单元格配置可以在cellForRowAtIndexPath或willDisplayCell: forRowAtIndexPath:"!
Glo*_*del 23
你是对的,单元配置可以(理论上)在两种方法中完成.
但是,几乎所有UITableView都有一个实现的数据源cellForRowAtIndexPath:(它是协议中的必需方法).另一方面,willDisplayCell:forRowAtIndexPath:(委托的方法,而不是数据源)是可选的.
由于配置单元通常取决于您要显示的数据,cellForRowAtIndexPath:因此目前是进行单元配置的最常见位置.(我甚至不记得使用willDisplayCell:forRowAtIndexPath:).
还有一个值得注意的例外情况:当你使用的是故事板和静态细胞(而不是细胞的原型),你不能做任何有用cellForRowAtIndexPath:(因为dequeueReusableCellWithIdentifier:回报率nil),所以你必须在做配置willDisplayCell:forRowAtIndexPath:,viewWillAppear:或其他方法.
@NSDeveloper:你是对的.谢谢你的提示.
Mar*_*ams 17
cellForRowAtIndexPath应该实际返回一个单元格实例.如果可能,它应该是重复使用的单元格.UITableViewDataSource协议需要此方法.这通常是您选择将在单元格中显示的数据的位置.对于动态单元格,在此处设置数据的同时设置UI属性(如选定状态)是很常见的.
willDisplayCell是可选的,并在之后调用.这是您在显示单元格之前自定义单元格的最后机会.此时,已经创建了单元实例.您可以在此处更改选定状态等内容.您不应该更改单元格的数据/结构或实例化任何新内容,而只是更改单元格的UI属性的状态.这通常与静态单元一起使用.
iTS*_*gar 16
我想这回答了你的问题:
但是仍然存在非常重要的事情: tableView:cellForRowAtIndexPath:方法,它应该在UITableView的dataSource中实现,为每个单元调用并且应该快速工作.因此,您必须尽快返回重用的单元实例.
此时不要执行数据绑定,因为屏幕上还没有单元格.为此,您可以使用 tableView:willDisplayCell:forRowAtIndexPath:方法,该方法可以在UITableView的委托中实现.该方法在UITableView的边界中显示单元格之前完全调用.
尽管看似直观,但将在调用cellForRowAt indexPath:之后立即调用willDisplay cell :。
我有一个应用程序,可以从URLCache加载图像和视频,或者将其下载并显示在单元格中。我注意到,无论何时启动应用程序,所有视频和图像都会先加载,然后才能看到它们,我注意到这一点,因为在查看tableView的第一项时,我可以听到tableView的最后一个视频的音频。这是tableView中的8个项目。我打印到控制台以更好地了解委托函数调用的顺序。
结果:
代码:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "feedCell", for: indexPath) as! FeedCell
print("Created cell at row \(indexPath.row)")
let post = posts[indexPath.row]
cell.post = post
cell.viewController = self
cell.configureCell()
return cell
}
override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if let feedCell = cell as? FeedCell{
print("Drew feed cell at row \(indexPath.row)")
// only want download task to start when the cell will display
if feedCell.post.isVideo {
feedCell.loadVideo()
} else {
feedCell.loadImage()
}
}
}
override func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) {
print("Stopped showing cell at row \(indexPath.row)")
if let feedCell = cell as? FeedCell{
feedCell.player?.pause()
}
}
Run Code Online (Sandbox Code Playgroud)
我在willDisplayCell:使用自动布局和UITableViewAutomaticDimension. 重复使用的单元格的高度无法正确计算。NSLog 中的打印方法显示willDisplayCell:在之后调用heightForRowAtIndexPath:(在 iOS 10.2 模拟器上测试)
cellForRowAtIndexPath: <NSIndexPath: 0x7c10daa0> {length = 2, path = 1 - 0}
heightForRowAtIndexPath: <NSIndexPath: 0x7c10daa0> {length = 2, path = 1 - 0}
heightForRowAtIndexPath: <NSIndexPath: 0x7c10daa0> {length = 2, path = 1 - 0}
willDisplayCell: <NSIndexPath: 0x7c10daa0> {length = 2, path = 1 - 0}
cellForRowAtIndexPath: <NSIndexPath: 0x7c4516f0> {length = 2, path = 1 - 1}
heightForRowAtIndexPath: <NSIndexPath: 0x7c4516f0> {length = 2, path = 1 - 1}
heightForRowAtIndexPath: <NSIndexPath: 0x7c4516f0> {length = 2, path = 1 - 1}
willDisplayCell: <NSIndexPath: 0x7c4516f0> {length = 2, path = 1 - 1}
Run Code Online (Sandbox Code Playgroud)
我认为这就是原因,因为将配置代码放入后问题就消失了cellForRowAtIndexPath:
PS 有一篇与@iTSangar 发布的链接和引用相反的文章:https://tech.zalando.com/blog/proper-use-of-cellforrowatindexpath-and-willdisplaycell/
| 归档时间: |
|
| 查看次数: |
18159 次 |
| 最近记录: |