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. あなたは画像のみの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

関連する問題