1

UICollectionViewFlowLayout私はいくつかの再利用性を備えたcollectionViewを持っています:

- (CategoryCell*)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    CategoryCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"CategoryCell" forIndexPath:indexPath];
    [cell.actIn startAnimating];
    cell.cellElementRepresentation = [self.localCategoriesObjects objectAtIndex:indexPath.row];
    [cell tryToShow]; //this is a important method to my problem

    return cell;
}

私はあなたのtryToShow方法についてコメントしました。これは問題だと思うからです。リスト内の表示されていない要素までスクロールすると、最初に「古い」要素が表示され、次に新しい要素が表示されました。何故ですか?私のtryToShow方法は基本的にダウンロードマネージャーです。私はコメントでそれを説明しようとします。コードは次のとおりです。

-(void)tryToShow {
    NSString* imageFile = self.linkToImageFileSavedOnDisk //This is my local file saved in documentsDirectory.

    if([[NSFileManager defaultManager] fileExistsAtPath:imageFile]) {
        [self.overlayButton setBackgroundImage:[UIImage imageWithContentsOfFile:imageFile] forState:UIControlStateNormal];
        [self disableActIn]; //Here i stop and remove activity indicator.
    } else {
        // Here i fire NSURLConnection and try to download. When NSURLConnection finished i put image to overlayButton.
    }
}

デリゲートメソッドは次のとおりです。

-(void)connectionDidFinishLoading:(NSURLConnection *)connection {
     //Here do some stuff to convert Data into UIImage... not important.
     [self.overlayButton setBackgroundImage:object forState:UIControlStateNormal];
}

overlayButton は 上のボタンUICollectionViewCellです。私はそれのためのカスタムクラスを持っています。

私はそれを理解することはできません。indexPath.rowスクロール後に(たとえば1)から画像を表示するにはどうすればよいですか?新しい画像が正常にダウンロードされた直後に新しい画像に置き換えられますが、これでは遅いです。

4

2 に答える 2

1

OPが言及しているように、設定がbackgroundImage遅すぎることが問題のようです。だから私はこの変更を試してみます:

  1. まず、新しい値を設定する前にセルをクリアします。セルを再利用しているため、セルのサブビューには古い値 (テキストと画像) が引き続き表示されます。これらの値を nil に設定すると、セルがクリアされます。

  2. 画像リクエストからの結果を検証または無効にするメカニズムを実装します。結果を取得するのが遅すぎる可能性があるため、不要になった可能性があります。最悪の場合、データと対応しなくなった画像を設定できます。ダウンロードした画像を設定する前に、この画像が現在表示されているデータと一致していることを確認する必要があります。

  3. 画像リクエストを開始する前に少し待ってください多数のセルがある場合、ユーザーがコレクションをすばやくスクロールすると、表示されない可能性のある画像のリクエストが多数開始される可能性があると考える必要があります。新しいリクエストを開始する前に少し待って、セルが再利用されたかどうかを確認することで、この動作を回避します。

  4. NSURLRequest を使用して、cachePolicy 属性を として構成しますNSURLRequestReturnCacheDataElseLoad。これにより、画像の応答が保存されます。画像を明示的に保存してその存在を確認する必要はありません。

于 2013-07-07T04:25:52.057 に答える
0

self.overlayButtonWebリクエストを開始するelse句で背景画像をnilに設定する必要があると思います。

[self.overlayButton setBackgroundImage:nil forState:UIControlStateNormal];

そうすれば、ユーザーがセルにスクロールしたときに、セルに既に画像が読み込まれているようには見えません。または、ロードが十分に速くない場合 (そうあるべきです)、collectionView:didEndDisplayingCell:forItemAtIndexPath:代わりにデリゲート メソッドで背景画像を nil に設定できます。

しかし、私が見る問題は、呼び出されるNSURLConnectionたびに重複するオブジェクトを作成することですtryToShow。つまり、ユーザーは下にスクロールしてから、一番上のセルに再度アクセスします。

@ lucaslt89 が示唆したように、デフォルトのデキューを使用する代わりに、セルの辞書を作成できます。このようにする場合は、セルに URL 接続オブジェクトのプロパティがあることを確認し、新しい接続を開始する前に確認します。

または、NSURLConnectionView Controller で作成したオブジェクトのディクショナリを作成し、Web リクエスト コードを View Controller に移動することもできます。Web リクエストが必要な場合、View Controller は最初にディクショナリで実行中の Web リクエストがすでに存在するかどうかを確認します。リクエストが終了すると、リクエスト オブジェクトはディクショナリから削除されます。セルは独自のデータを作成する責任がないため、これは望ましい方法です。セル内ではUICollectionView役割をすばやく変更する必要があり、セルが本当に少ない場合を除き、特定のセルをデータに関連付けることは賢明ではありません。

いずれにせよ、同じ画像に対して複数のURL リクエストを作成することは避けられます。

お役に立てれば!

于 2013-07-07T04:26:47.887 に答える