在iOS应用程序中下载图像并在collectionView单元格中显示这些图像

时间:2014-03-25 13:43:39

标签: ios iphone ipad ios7 uicollectionview

我正在使用此方法下载图片:

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单元格中显示它们......

是不是这样做的正确方法...... 如果是,那么我该怎么做才能在阵列中保存多个图像并在集合视图中显示它们 任何想法/帮助............ ..

3 个答案:

答案 0 :(得分:3)

调用 - [UIImage initWithData:]方法仅在图像数据已存在于文件系统上时才有效。你不想做的是下载一堆图像并将它们保存在一个数组中。原因是您不希望所有这些图像都驻留在内存中(尤其是那些不可见的图像)。

虽然有些图书馆可以帮助您,但我会鼓励您自己尝试这种策略,因为在我看来您还不熟悉iOS。

根据我对您的问题的理解,您将需要解决以下概念

  1. 图像磁盘存储策略
  2. 图像文件路径检索
  3. 网络
  4. 集合视图集成
  5. 图像磁盘存储策略

    假设您要将这些图像保存到磁盘并在下次应用启动时使用它们,那么您将需要阅读https://developer.apple.com/library/mac/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/FileSystemOverview/FileSystemOverview.html以了解这些图像应存储在磁盘上的位置。例如,使用TMP目录获取应用程序可以轻松再次获取的资源,并且您不希望它们备份。

    图片文件路径检索

    由于您使用某种形式的数据源填充集合视图,因此该数据源还应负责返回给定索引路径上的图像的文件路径。这样,当您的集合视图查询其特定索引路径上的单元格的数据源时,您将获取所述单元格的所有相关信息并适当地配置您的单元格。在您的情况下,此数据源将仅为特定索引处的给定图像提供本地和远程文件路径。

    集合视图中的项目数应该会影响您用于设计数据源的策略。如果只有少量文件路径(< 10),那么您可以使用NSDictionary,其中键是indexPath,对象是您的filePath。如果你有很多图像,你肯定需要一个持久性框架来避免将所有图像路径放入驻留在内存中的一个对象中。一种解决方案是将文件路径保存到核心数据中的图像中,这样您就可以使用获取的结果控制器与集合视图协调。这意味着将每个indexPath获取filePath到映像,然后在collectionViewCell上设置它。 Core Data提供了一个非常棒的对象持久性框架,可以让您立即启动并运行。

    <强>网络

    您需要解决的另一个问题是在用户滚动时管理下载。例如,如果您在FIFO队列中下载,则在连接速度较慢时,如果用户滚动到集合视图的末尾,则首先添加的图像将保留队列,并且您不会在结束时看到图像,直到下载所有其他图像。一种解决方案是取消对不再可见的单元格的请求。 http://blog.yangmeyer.de/blog/2012/12/16/uitableviewcell-subclasses-and-async-loading是一篇使用GCD异步渲染单元格的文章。

    有很多不同的方法可以接近网络,所以它最终取决于你需要什么。有些人更喜欢对UIImageView进行子类化,以便为UIImageView提供自动从给定URL下载图像的功能。您可以通过提供远程URL和本地文件路径URL来实例化此类,然后如果本地路径上不存在任何内容,则自定义子类将触发下载。如果您实现此策略,您将要添加取消此自定义子类的下载的功能。

    集合视图集成

    您的收藏视图将负责将所有上述组件集成在一起。这意味着要获取要显示的图像数量,使用这些图像填​​充集合视图,便于网络的使用以及取消对不可见图像的图像请求。

    您要解决的重要事项是充分利用并发API。您的网络呼叫不应阻止主线程。我建议创建一个管理所有下载的NSOperationQueue。这样,当您关闭集合视图时,您可以取消该队列上的所有操作:)

答案 1 :(得分:1)

你的方式不是好方法。因为,您下载图像的每个图像都将其保存在设备中,而不是在UICollectionViewCell中显示。看起来您的图像不是很大,但不要忘记设备内存是有限的。所以,除非你真的需要,否则你不应该那样使用它。

此外,您不需要在UICollectionViewCell中显示之前保存所有图像,但您可以做的是懒洋洋地加载图片。您可以使用许多第三方库来实现这一目标,但我的建议是SDWebImage。您可以从文档中阅读更多内容并查看示例。您会发现使用起来非常简单。大多数过程对您来说都是透明的。你只需要设置图片网址,然后它就会为你处理一切。

答案 2 :(得分:0)

在集合视图中加载图像是不正确的方法,使用图像延迟加载方法在集合视图中加载图像,请参阅此示例代码以进行图像延迟加载==&gt; EGOImageLoading