1

我试图从URL中显示一些图像到我的集合视图。但是当我尝试这样做时,我的图像显示在集合视图上,但它们随机保持刷新和重新加载。另外当我尝试滚动collectionView,它再次重新加载整个数据,我不想要。我只想将图像显示为预览给用户。 下面是我的代码,从URL获取图像并将其显示在集合视图中。如何停止在CollectionView中自动重新加载和刷新图像iOS

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath 
{ 
UICollectionViewCell *cell=[collectionView dequeueReusableCellWithReuseIdentifier:@"cellIdentifier" forIndexPath:indexPath]; 

__block NSString *filename;  

for(NSDictionary *item in [jsonSD objectForKey:@"Data"]) {  
     for (int i=0; i<=[[item objectForKey:@"Count"]integerValue]; i++) { 
     filename=[NSString stringWithFormat:@"http://..URL../media/content/%@%@%d_1.png",_getstring,[item objectForKey:@"subcategory_id"],i]; 
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{  
       NSURL *url = [NSURL URLWithString:filename]; 
        [self downloadImageWithURL:url completionBlock:^(BOOL succeeded, NSData *data) { 
           if (succeeded) { 
            iv.image = [[UIImage alloc] initWithData:data];           
           } 
            }]; 

         }); 
    } 
    } 

return cell; 
} 

- (void)downloadImageWithURL:(NSURL *)url completionBlock:(void (^)(BOOL succeeded, NSData *data))completionBlock 
{ 
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; 
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) { 
    if (!error) { 
     completionBlock(YES, data); 
    } else { 
     completionBlock(NO, nil); 
    } 
}]; 
} 

这里'iv'是我的imageView,其中我显示的图像收集视图的单元格。 我试过搜索相关内容,但对上述问题我没有任何想法。

请帮帮我。任何帮助表示赞赏。

回答

1

所以好像这里有两个问题:

的第一个问题是:

cellForItemAtIndexPath 

被调用每一次细胞出现屏幕,这意味着如果你卷动那么downloadImageWithURL将在每次单元出现在屏幕上时被调用。

第二个问题似乎是,多个图片加载与for (int i=0; i<=[[item objectForKey:@"Count"]integerValue]; i++)

这个循环似乎下载多个图像中的每个单元格,然后将它们依次在同一个小区?

一些解决方案的第一个问题:

  1. 如果你只需要显示一些项目,加载所有的图像viewDidLoad和更新数据源每一次的一个图像已经下载。
  2. 每个单元格的图像下载后,将其添加到数组中。每次单元加载时,检查数组是否包含该单元的图像,并使用该单元而不是下载新单元。

第二个问题:

什么不确定的循环意味着在这里实现,你想要从环路中的每个图像显示在它自己的集合视图电池?

更新时间:

这里有一个简单的例子向您展示的代码的外观。我不知道什么是包含在jsonSD或部分代码的其他部分,但它应该给你正确的观念:

@interface TestCollectionViewController() { 
NSMutableArray *datasource; 
NSDictionary *jsonSD; 
} 


@end 

@implementation TestCollectionViewController 

static NSString *const reuseIdentifier = @"Cell"; 

- (void)viewDidLoad { 
[super viewDidLoad]; 

// We want to load the data from all cells as soon as the view loads, instead of loading the data as the cells scroll. 
// Lazy loading cells will require a more advanced implementation 

[self loadDatasource]; 

} 

- (void)loadDatasource { 

for (NSDictionary *item in [jsonSD objectForKey:@"Data"]) { 

    // Fill the datasource with null objects which match the total number of objects you want to display 

    datasource = [NSMutableArray arrayWithCapacity:[[item objectForKey:@"Count"] integerValue]]; 

    for (int i = 0; i <= [[item objectForKey:@"Count"] integerValue]; i++) { 

     [datasource addObject:[NSNull null]]; 

    } 

    // Reload the collectionview now so that the empty cells will be displayed with no image. 

    [self.collectionView reloadData]; 

    // Load each image individually and replace the corresponding NSNull in the datasource. 

    for (int i = 0; i <= [[item objectForKey:@"Count"] integerValue]; i++) { 

     NSString *filename = [NSString stringWithFormat:@"http://..URL../media/content/%@%@%d_1.png", _getstring, [item objectForKey:@"subcategory_id"], i]; 

     NSURL *url = [NSURL URLWithString:filename]; 
     [self downloadImageWithURL:url completionBlock:^(BOOL succeeded, NSData *data) { 
      if (succeeded) { 

       [datasource replaceObjectAtIndex:i withObject:[UIImage imageWithData:data]]; 

       // Reload the collectionview after each item has downloaded so the image gets displayed in the cell. 

       [self.collectionView reloadData]; 
      } 
     }]; 

    } 
} 
} 

- (void)downloadImageWithURL:(NSURL *)url completionBlock:(void (^)(BOOL succeeded, NSData *data))completionBlock { 
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; 
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) { 
    if (!error) { 
     completionBlock(YES, data); 
    } else { 
     completionBlock(NO, nil); 
    } 
}]; 
} 

#pragma mark <UICollectionViewDataSource> 

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView { 

// Only displaying one section 

return 1; 
} 

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { 
return datasource.count; 
} 

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { 
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath]; 

// Configure the cell 

if ([datasource objectAtIndex:indexPath.row] == [NSNull null]) { 

    // Display a default image here 

} else { 

    // Image has been loaded, display it in the imageview 

    iv.image = [datasource objectAtIndex:indexPath.row]; 
} 

return cell; 
} 

更新2:

上面的答案是不可怕如果您拥有数百件物品,效率并不会太高。为了更稳定的实现,我建议使用像SDWebImage这样的库来为您处理它。那么你可以做一些简单的事情:

[cell.imageView setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"] 
      placeholderImage:[UIImage imageNamed:@"placeholder.png"] 
        completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType) {... completion code here ...}]; 
+0

你发现它是正确的。我不想在一个单元格中显示所有图像。我想单个单元格的单个图像。 – ammy1

+0

你能帮我吗。 – ammy1

+0

@ Greg-感谢您的建议。我会试试看。 – ammy1

0

我不明白你想要做什么,当你滚动你的集合视图时,它总是会获取图像数据,因为重用机制。您可以在viedDidLoad()方法中获取图像数据,在完整获取图像数据后重新加载您的收藏视图。

+0

ok。我会尝试你的建议。 – ammy1

相关问题