我有代表事件的海关单元格的TableView。它看起来非常接近这里的第一和第三张图像。

正如你所看到的(对于小解析度很抱歉),在一些活动中,有一些朋友的照片将要参加。不幸的是,关于朋友的信息并没有加载其他有关事件的信息。
因此,在我得到事件列表之后,我可以请求加载将要参加每个活动的朋友列表。
现在,我使用的代码如下
class EventCell : UITableViewCell {
var eventForCell : Event? {
didSet {
eventTitleLabel.text = eventForCell.title
eventDateLabel.text = eventForCell.date
presentFriends(eventID : eventForCell.id)
}
}
func presentFriends(eventID : Int) {
//searching for friends for event with specific eventID
.......
.......
//for every friend found adding UIImageView in cell
for friend in friendsOnEvent {
let avatar = UIImageView(....)
self.addSubview(avatar)
}
}
}此代码工作,但照片并不是以平滑的方式呈现。另外,如果你滚动列表快,他们开始眨眼。如果用户滚动快速事件列表,甚至没有必要加载它们。所以我有两个问题:
更新:
我在tableView(_:prefetchRowsAt:)协议中找到了有关UITableViewPrefetchingDataSource方法的信息,我应该在这个例子中使用它吗?也许有人在这方面有经验?
发布于 2018-03-23 09:49:14
1. (Re)在cellForRowAt期间创建视图对象通常是一种糟糕的做法。从屏幕截图中,我假设一个单元格上有多少个化身是有限度的--我建议在单元格初始化器中创建所有的UIImageView对象,然后在presentFriends中将图像设置给它们,或者隐藏未使用的图像(isHidden = true),或者将它们的alpha设置为0(当然,不要忘记隐藏正在使用的图像)。
2.如果您正在使用SDWebImage加载映像、实现prepareForReuse和取消当前下载以在滚动期间获得一些性能提升,并防止未定义的行为(当您试图设置另一个映像,而之前的映像尚未下载时)。基于这个问题、这一个和这一个,我希望这样的事情:
override func prepareForReuse() {
super.prepareForReuse()
self.imageView.sd_cancelCurrentImageLoad()
}
Or you can use [this gist][4] for an inspiration.P.S.:,由于图片是从网络下载的,所以你必须用闪烁的方式来计数--总是会有一些延迟。通过缓存,您可以立即获得已经下载的图像,但是新的缓存将延迟--这是无法阻止的(除非您在呈现tableView之前预先加载tableView中的所有图像)。
P.S.2:您可以尝试使用[UITableViewDataSourcePrefetching][6]实现预取。这可以帮助您通过下载从网络上的化身闪烁。这会使事情变得更复杂,但如果你真的想消除闪烁,你将不得不弄脏你的手。
首先,正如您可以从文档中看到的那样,prefetchRowsAt不会给您一个单元对象--因此您必须将图像预取到您的模型对象,而不是简单地在给定单元格上对UIImageView对象使用sd_setImage。也许前面提到的要旨会帮助你下载图片来建模。
现在,正如文档声明的那样:
异步加载数据 对于表视图中的每个单元格,不一定要调用
tableView(_:prefetchRowsAt:)方法。因此,tableView(_:cellForRowAt:)的实现必须能够处理以下潜在情况: 数据已通过预取请求加载,并已准备好显示。 数据目前正在预取,但尚未可用。 尚未要求提供数据。
简单地说,当您在cellForRowAt中时,您不能依赖调用prefetchRowsAt --它可能已经被调用,也可能没有被调用(或者调用正在进行中)。
文档继续建议使用Operation作为下载资源的支持工具-- prefetchRowsAt可以创建负责为给定行下载化身的Operation对象。然后,cellForRowAt可以询问给定行的Operation对象的模型--如果没有,这意味着没有为该行调用prefetchRowsAt,因此必须在此时创建Operation对象。否则,您可以使用prefetchRowsAt创建的操作。
无论如何,如果您认为这是值得的,您可以使用这个教程作为实现预取的灵感。
发布于 2018-03-23 09:52:22
您可以像前面提到的那样使用UITableViewDataSourcePrefetching。
这是一种协议,当要显示一些单元时调用预取数据源,但尚未显示在屏幕上。
通过这种方式,您可以准备所有需要时间加载的资源,然后才会显示它们。
你只需要实现:
func tableView(_ tableView: UITableView, prefetchRowsAt indexPaths: [IndexPath])并从所有indexpaths中获取与单元格相关的数据。
请注意,它只在iOS10之后才可用。
我个人在缓存中使用AlamofireImage,这样已经下载的图像不会被抓取两次,有很多替代方法,但是在这种情况下使用缓存的映像是一个很好的实践。
https://stackoverflow.com/questions/49346881
复制相似问题