UITableView与来自API的图像
UITableView是一种以列表方式显示结构化数据的好方法。 与Android不同,iOS在促进开发人员使用UITableView方面做得很好。 当您的应用程序显示来自API调用的数据时,事情的学习曲线确实陡峭。 在这里曲线不会停止变陡。 如果您计划在UITableViewCell中显示图像,它将变得有些棘手。 这正是我们今天要做的。
我们打算做什么?
我不打算深入研究UITableView实现。 我给你创造的自由,可以根据需要设计UITableViewCell并使基本应用程序正常工作。 首先使用虚拟数据和占位符图像测试UITableView始终是一个好主意。
一旦您的UITableView启动并运行了虚拟数据和占位符图像,请从GitHub API获取内容。
您可以通过请求以下URL来获得您的GitHub关注者。
https://api.github.com/users/ / followers
API响应将具有许多键值。 我们将限制本帖子的图片和名称。
假设您知道如何进行网络调用和解析响应数据以显示在UITableViewCell上,现在让我们集中讨论您应该面对的两个问题
- 表格视图滚动很慢。
- 滚动UITableView时,图像会更改。 用户A的个人资料图片可能与用户B的名字一起出现
问题1:为什么UITableView滞后?
当您尝试在UITableViewCell的UIImageView上呈现图像时,将进行网络调用,该网络调用将从图像url获取图像数据,然后使用响应数据创建图像。
每次创建单元时都会发生这种情况。 假设您有3个UITableViewCells,那么将有3个网络调用来获取每个单元格的图像。 当我们处理更多单元格时,随着UITableView重用单元格,此问题会放大。
我如何摆脱时滞?
为了恢复完美的滚动效果,我们可以使用多任务处理。 我们将在后台获取图像数据,并且在接收到图像数据后,将用从API调用接收到的图像替换占位符图像。
在cellForRowAtIndexPath中,
DispatchQueue.global(qos:.background).async {
让url = URL(string:(activeUser?.avatarUrl)!)
让数据=尝试? 数据(contentsOf:url!)
让图像:UIImage = UIImage(data:data!)!
DispatchQueue.main.async {
self.imageCache.setObject(image,forKey:NSString(string:(activeUser?.login!)!))
cell.imgFollow.image =图片
}
}
但是,如果图像数据从未收到怎么办?
这是占位符为您提供帮助的地方。 如果未接收到图像数据,则UITableViewCell将具有占位符图像。
问题2:为什么图像在滚动时会不断变化?
如上所述,每次创建UITableViewCell时都会进行网络调用。 说,您的单元格已创建,图像请求已发出,但是在图像响应完成之前,您滚动到另一个单元格。 tableview不知道数据。 它只是按照提示进行操作,并将图像数据粘贴到图片中的表格单元格上的图像上。
如何防止这种情况发生?
更好的方法是利用缓存。 我们现在
- 创建单元格时获取图像。 每个图像只需下载一次。
- 使用合适的密钥(例如登录ID)缓存图像。
- 每次重复使用或创建单元时,请检查缓存中的图像
- 如果图像在缓存中,请从缓存中加载图像。
- 如果图像不在缓存中,请进行网络调用以获取它并将其存储在缓存中。
初始化缓存:
让imageCache = NSCache ()
将图像保存在缓存中:
self.imageCache.setObject(image,forKey:NSString(string:(activeUser?.login!)!))
加载图像:
如果让cachedImage = imageCache.object(forKey:NSString(string:(activeUser?.login!)!))){
cell.imgFollow.image =缓存的图像
}其他{
//进行网络通话以获取图像
}
这是完整的GitHub项目,我在其中使用了这些代码段。