14

をサムネイルとして使用してUIImageViewいます。UITableViewCells私のコードはSDWebImage、これらの画像をバックエンドから非同期に取得して読み込み、キャッシュするために使用します。これはうまくいっています。

MyUIImageViewは、Interface Builder で作成された 50x50 の正方形です。その背景は不透明な白色です (パフォーマンスのために、私の背景色と同じUITableViewCellです)。ただし、見栄えを良くするために滑らかな角を使用したいと思います。私がこれを行う場合:

UIImageView *itemImageView = (UIImageView *)[cell viewWithTag:100];
    itemImageView.layer.cornerRadius = 2.5f;
    itemImageView.layer.masksToBounds = NO;
    itemImageView.clipsToBounds = YES;

私のテーブルビューはすぐに約 5 ~ 6 フレーム低下し、高速スクロール中は約 56 FPS に制限されます (これは問題ありません) が、リフレッシュ コントロールをドラッグ アンド プルすると、少し遅れて約 40 FPS に低下します。行を削除するとcornerRadius、すべて問題なく、遅延はありません。これは、Instruments を使用して iPod touch 5G でテストされています。

UIImageViewセルを丸め、パフォーマンスに影響を与えないようにする他の方法はありますか? 私はすでに最適化してcellForRowAtIndexPathおり、 no を使用して高速スクロールしているときに 56-59 FPS を取得していcornerRadiusます。

4

4 に答える 4

32

はい、それは cornerRadius と clipToBounds がオフスクリーン レンダリングを必要とするためです。私の質問の 1 つからこれらの回答を読むことをお勧めします。また、ご覧になるべき 2 つの WWDC セッションを引用します。
あなたができる最善のことは、 がダウンロードされた直後に画像を取得し、別のスレッドで画像を丸めるメソッドをディスパッチすることです。イメージビューではなくイメージで作業することをお勧めします。

// Get your image somehow
UIImage *image = [UIImage imageNamed:@"image.jpg"];

// Begin a new image that will be the new image with the rounded corners 
// (here with the size of an UIImageView)
 UIGraphicsBeginImageContextWithOptions(imageView.bounds.size, NO, 1.0);

 // Add a clip before drawing anything, in the shape of an rounded rect
  [[UIBezierPath bezierPathWithRoundedRect:imageView.bounds 
                        cornerRadius:10.0] addClip];
 // Draw your image
[image drawInRect:imageView.bounds];

 // Get the image, here setting the UIImageView image
  imageView.image = UIGraphicsGetImageFromCurrentImageContext();

 // Lets forget about that we were drawing
  UIGraphicsEndImageContext();

ここで取得されたメソッド また、tableviewcell をサブクラス化し、drawRect メソッドをオーバーライドすることもできます。
汚いが非常に効果的な方法は、Photoshop でセルの背景色と一致する色の内側のアルファを使用してマスクを描画し、画像のあるものに、透明な背景色で不透明ではない別の imageView を追加することです。

于 2013-07-11T12:44:29.583 に答える
5

ノンブロッキング ソリューション

Andrea の応答のフォローアップとして、彼のコードをバックグラウンドで実行する関数を次に示します。

+ (void)roundedImage:(UIImage *)image
          completion:(void (^)(UIImage *image))completion {
    dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        // Begin a new image that will be the new image with the rounded corners
        // (here with the size of an UIImageView)
        UIGraphicsBeginImageContextWithOptions(image.size, NO, image.scale);
        CGRect rect = CGRectMake(0, 0, image.size.width,image.size.height);

        // Add a clip before drawing anything, in the shape of an rounded rect
        [[UIBezierPath bezierPathWithRoundedRect:rect
                                    cornerRadius:image.size.width/2] addClip];
        // Draw your image
        [image drawInRect:rect];

        // Get the image, here setting the UIImageView image
        UIImage *roundedImage = UIGraphicsGetImageFromCurrentImageContext();

        // Lets forget about that we were drawing
        UIGraphicsEndImageContext();
        dispatch_async( dispatch_get_main_queue(), ^{
            if (completion) {
                completion(roundedImage);
            }
        });
    });
}
于 2015-04-13T23:18:37.020 に答える