在 iOS 应用程序中下载图像并在 collectionView 单元格中显示这些图像
Posted
技术标签:
【中文标题】在 iOS 应用程序中下载图像并在 collectionView 单元格中显示这些图像【英文标题】:download images in iOS app and show these images in collectionView cells 【发布时间】:2014-03-25 13:43:38 【问题描述】:我正在使用这种方法下载图片:
image = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://upload.wikimedia.org/wikipedia/en/d/d8/Url-logo.png"]]];
// save file.
//NSString *documentDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
//NSLog(@"%@", documentDir);
NSLog(@"Saving Image");
NSString *imagePath = [NSString stringWithFormat:@"%@/Url-logo.png",documentDir];
NSData *imageData = [NSData dataWithData:UIImagePNGRepresentation(image)];
[imageData writeToFile:imagePath atomically:YES]; */
NSLog(@"image Saved");
现在我想下载多个图像,然后保存在一个数组中……然后使用数组的 indexPaths 在 CollectionView 单元格中显示它们……
这是正确的方法吗... 如果是,那么我应该怎么做才能将多个图像保存在数组中并在集合视图中显示它们 任何想法/帮助…………..
【问题讨论】:
嗨 Zaibi,也许您是 *** 的新手,但我们很多人都在回答用户问题上付出了很多努力。回答问题对双方都有好处,对每个人来说都是一次很好的学习体验。您目前对您的问题有 2 个答案,但您尚未在 cmets 中回复它们。请为问题投票或在 cmets 中参与辩论,但不要让这个问题无人看管。 @DanielG 抱歉回复晚了……实际上我最近几个小时都不在那儿……好消息是我已经解决了我的问题……感谢您的合作和支持 不用担心 Zaibi,如果您已经设法解决了问题,请提供您的答案或投票给对您有帮助的答案,这样其他有相同问题的人都可以在这里学到一些东西:) 【参考方案1】:仅当图像数据已经在文件系统上时,调用 -[UIImage initWithData:] 方法才有效。您不想做的是下载一堆图像并将它们保存在一个数组中。这样做的原因是您不希望所有这些图像都驻留在内存中(尤其是那些不可见的图像)。
虽然有一些库可以帮助你,但我鼓励你自己尝试这种策略,因为在我看来你还不熟悉 ios。
根据我对您问题的理解,您将需要解决以下概念
-
图像磁盘存储策略
图像文件路径检索
网络
集合视图集成
图像磁盘存储策略
假设您想将这些图像保存到磁盘并在下次应用启动时使用它们,那么您将需要阅读https://developer.apple.com/library/mac/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/FileSystemOverview/FileSystemOverview.html 以了解这些图像应该存储在磁盘上的什么位置。例如,将 TMP 目录用于 App 可以轻松再次获取且您不希望它们备份的资源。
图像文件路径检索
由于您正在使用某种形式的数据源填充集合视图,因此该数据源还应该负责返回给定索引路径处图像的文件路径。这样,当您的集合视图在特定索引路径中查询其数据源以查找单元格时,您将获取该单元格的所有相关信息并适当地配置您的单元格。在您的情况下,此数据源将仅在特定索引处为给定图像提供本地和远程文件路径。
您的集合视图中的项目数量应该会影响您用于设计数据源的策略。如果只有几个文件路径(
网络
您需要解决的另一个问题是在用户滚动时管理下载。例如,如果您在 FIFO 队列中下载,则连接速度较慢,那么如果用户滚动到集合视图的末尾,则首先添加的图像将占用队列,并且您将不会看到最后的图像,直到每隔一个图像已下载。一种解决方案是取消对不再可见的单元格的请求。 http://blog.yangmeyer.de/blog/2012/12/16/uitableviewcell-subclasses-and-async-loading 就是这样一篇使用 GCD 异步渲染单元格的文章。
有很多不同的方式可以处理网络,因此最终取决于您的需求。有些人更喜欢对 UIImageView 进行子类化,以便为 UIImageView 提供自动从给定 URL 下载图像的功能。您可以通过提供远程 URL 和本地文件路径 URL 来实例化此类,然后如果本地路径中不存在任何内容,则自定义子类将触发下载。如果您实施此策略,您将希望添加取消此自定义子类的下载的功能。
集合视图集成
您的集合视图将负责将上述所有组件集成在一起。这意味着获取要显示的图像数量、用这些图像填充集合视图、促进网络的使用以及取消对不可见图像的图像请求。
您要解决的重要问题是充分利用并发 API。您的网络调用不应阻塞主线程。我建议创建一个管理所有下载的 NSOperationQueue。这样,当您关闭集合视图时,您可以取消该队列上的所有操作:)
【讨论】:
感谢详细的描述……让我试试这个…… 你的意思是,不需要下载图片并保存在设备/应用文件目录下。但是如果应用程序必须离线运行……那么图像如何下载并显示在单元格中…… 如果您希望它们离线,您绝对应该将它们保存到磁盘。我的意思是您应该将它们保存到磁盘并将文件路径存储在持久性框架中。因此,当您保存图像时,您将其保存在某处,然后当您想要检索它时,您调用 [UIImage initWithContentsOfFile:pathToImage]; 我更新了我的答案,希望对您有所帮助。如果我感到困惑,请告诉我【参考方案2】:你的方法不是很好的方法。因为,您下载的每张图片都保存在设备中,而不是显示在UICollectionViewCell
中。看起来您的图像不是那么大,但不要忘记设备内存是有限的。所以,除非你真的需要它,否则你不应该真的那样使用它。
另外,在UICollectionViewCell
中显示之前,您不需要保存所有图像,但您可以做的是延迟加载图像。您可以使用许多第三方库来完成此操作,但我的建议是 SDWebImage。您可以从文档中阅读更多内容并查看示例。你会发现它使用起来真的很简单。大部分过程对您来说都是透明的。您只需要设置图片网址,它就会为您处理一切。
【讨论】:
【参考方案3】:在collection view中加载图片的方式不正确,使用imagelazy loading方法在collection view中加载图片,图片延迟加载参考这个示例代码==>EGOImageLoading
【讨论】:
以上是关于在 iOS 应用程序中下载图像并在 collectionView 单元格中显示这些图像的主要内容,如果未能解决你的问题,请参考以下文章
如何在 iOS Swift 中显示库中的实时照片视频并在 Collection-View 中显示?
如何支持IOS6和IOS7应用图标并在同一个应用中启动图像?