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

相關問題