web-dev-qa-db-ja.com

UICollectionviewセルのロード時にスクロールが途切れる

アプリにUICollectionViewを使用するギャラリーがあります。セルのサイズは約70,70です。リストに保存したギャラリーのALAssetsからALAssetLibraryを使用しています。

私は、セルを埋めるために通常のパターンを使用しています:

-(UICollectionViewCell*)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{

  mycell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
  mycell.imageView.image = [[UIImage imageWithCGImage:[alassetList objectAtIndex:indexpath.row] thumbnail]];
  return mycell;
}

私のギャラリーは途切れ途切れにスクロールしています。これがなぜなのか分かりません。 NSCacheを追加してサムネイル画像をキャッシュしようとしました(画像の作成は多分高額だったと思います)が、これはパフォーマンスに役立ちませんでした。

UIは、ストックアプリと同じくらいバタフライになると思います。

私は今、それがUICollectionViewCell prepareForReusedequeueReusableCellWithReuseIdentifierメソッドを保持している可能性がありますが、機器を使用してこれを見つけることができませんでした。

これを引き起こしている可能性のある他の何か? UICollectionViewCellを準備する、またはdequeueをより高速に準備する「より高速な」方法はありますか?

33
Avner Barr

したがって、スクロールの問題がある人は誰でも this

デキュー後にこれらの2行を追加します

cell.layer.shouldRasterize = YES;
cell.layer.rasterizationScale = [UIScreen mainScreen].scale;
95
Avner Barr

「途切れ」はUIImageの割り当てによるものであり、dequeueReusableCellWithReuseIdentifierメソッドに関するものではないと考えます。バックグラウンドスレッドで画像の割り当てを行い、それが少しバタフライになるかどうかを確認します。

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

  dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^(void) {
     // Load image on a non-ui-blocking thread
    UIImage *image = [[UIImage imageWithCGImage:[alassetList objectAtIndex:indexpath.row] thumbnail]];

    dispatch_sync(dispatch_get_main_queue(), ^(void) {
        // Assign image back on the main thread
        mycell.imageView.image = image;
    });
  });

  return mycell;
}

詳細はこちらをご覧ください: https://developer.Apple.com/library/ios/documentation/Cocoa/Conceptual/Multithreading/Introduction/Introduction.html

19
preynolds

NSURLConnectionのsendAsynchronousRequest:queue:completionHandler:を使用して画像を読み込みます

NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
    [cell.imageView setImage:[UIImage imageWithData:data]];
}];
8
Beau Hankins

クリップのサブビューをオンにし、属性インスペクターで不透明にし、ページングを有効にします。

2
A.G

UICollectionViewスクロールに問題がありました。

(ほとんど)私にとって魅力のように働いたもの:私はセルにPNGサムネイル90x90を入れました。最初の完全なスクロールはそれほど滑らかではないが、もうクラッシュすることはないため、私はほとんど言う...

私の場合、セルサイズは90x90です。

以前に多くの元のpngサイズがありましたが、pngの元のサイズが〜1000x1000を超えると非常に不安定になりました(最初のスクロールで多くのクラッシュが発生しました)。

そのため、UICollectionViewで90x90(など)を選択し、元のpng(サイズに関係なく)を表示します。これが他の人に役立つことを願っています。

0
Paulo Souto

コレクションビューでの作業経験を共有します。

Swift 5

iOS 10 +を実行している場合、パフォーマンスはiOSの以前のバージョンよりもすでに優れているはずです。このWWDCビデオをご覧になることを強くお勧めします- iOS 10のUICollectionViewの新機能

パフォーマンスを向上させた本当に簡単なことの1つは、prefetchingデリゲートを実装することだけでした。文字通り、実装する以外に何もしませんでした!

  • 最初に、collectionViewがデリゲートに準拠していることを確認し、

    yourCollectionView.prefetchDataSource = self
    
  • 次に、先読みデリゲートを実装するだけで、

    extension YourViewController: UICollectionViewDataSourcePrefetching {
        func collectionView(_ collectionView: UICollectionView, prefetchItemsAt indexPaths: [IndexPath]) {
            // You could do further optimizations here.
        }
    }
    
0
Rakesha Shastri

誰かがPhImageManagerを使用している場合、同期をオフにすると問題は解決しました。 (deliveryMode = .FastFormatはパフォーマンスをさらに向上させることもできますが、トレードオフはサムネイルの品質が低下することです)

    let option = PHImageRequestOptions()
    option.deliveryMode = .Opportunistic
    option.synchronous = false
    PHImageManager().requestImageForAsset(phAsset, targetSize: CGSizeMake(2048, 2048), contentMode: .AspectFit, options: option, resultHandler: { (image, objects) in
        self.imageView.image = image!
    })
0
NoWhereToBeSeen