2013-07-11 16 views
13

benim için her biri için UIImageView kullanıyorum, küçük resimler olarak. Kodum, bu görüntüleri eşzamansız olarak arka ucumdan yakalayıp yükleyip sonra önbelleğe almak için SDWebImage kullanıyor. Bu iyi çalışıyor.Bir UITImageView'de bir UIImageView üzerinde köşeRadius'u kullanma

UIImageView, Arabirim Oluşturucu'da oluşturulan 50x50 karedir. Arka planı opak, beyaz renktir (performans için UITableViewCell arka plan rengim ile aynıdır). Bununla birlikte, daha iyi estetik için pürüzsüz köşeler kullanmak isterim.

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

Benim tableview (tamam) hızlı kaydırma esnasında 56 FPS hakkında kapatma, 5-6 kare hemen etrafında düşer, ama sürükleyip Yenileme denetimini çekin, bunun biraz kalıyor ve: Eğer bunu yaparsam yaklaşık 40 FPS'ye düşer. cornerRadius satırını kaldırırsam, her şey yolunda ve gecikmez. Bu cihazlar kullanılarak bir iPod touch 5G üzerinde test edilmiştir.

Hücrelerim için UIImageView yuvarlatılmış başka bir yol var mı? Zaten cellForRowAtIndexPath benim optimize edilmiş ve ben cornerRadius ile hızlı kaydırma yaparken 56-59 FPS aldım.

cevap

30

Evet, çünkü cornerRadius ve clipToBounds ekran görüntüsü oluşturma gerektirdiğinden, bu cevabı question numaralı telefonumdan okumanızı öneririz. Ayrıca, görmeniz gereken iki WWDC oturumu da alıntı yapıyorum.
Yapabileceğiniz en iyi şey, görüntü indirildikten hemen sonra ve başka bir iş parçacığı üzerinde görüntüleri döndüren bir yöntem göndermektir. Imageview yerine görüntü üzerinde çalışmanız tercih edilir.

// 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(); 

Yöntem Ayrıca tableviewcell alt sınıf ve drawRect yöntemini geçersiz kılabilir here yakaladı.
Kirli ama çok etkili bir yol, photoshop'ta alfa ile ve hücrenin arka planının eşleşen renginin etrafında bir maske çizerek, resimlerle birlikte açık arka plan rengiyle opak olmayan başka bir imageView ekleyin.

3

Bunun için başka iyi bir çözüm var. Projelerimde birkaç kez yaptım. Yuvarlatılmış köşeler veya başka bir şey oluşturmak istiyorsanız ana resminizin önünde bir kapak resmi kullanabilirsiniz. Örneğin, köşeleri yuvarlatmak istiyorsunuz. Bu durumda, merkezde bir kesik çemberi olan bir kare görüntü katmanına ihtiyacınız vardır. Bu yöntemi kullanarak, UITableView veya UICollectionView içinde kaydırma yapmak için 60 fps alırsınız. Bu yöntem, UIImageView'leri (avatarlar vb. Gibi) özelleştirmek için ekran görüntüsü oluşturma gerektirmediğinden.

4

Sigara engelleme çözümü

bir takibini Andrea'nın yanıtı gelince

, burada arka planda onun kod çalışacak bir fonksiyonudur.

+ (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); 
      } 
     }); 
    }); 
} 
0

Swift 3 thedeveloper3124 en cevabın versiyonu

func roundedImage(image: UIImage, completion: @escaping ((UIImage?)->(Void))) { 
    DispatchQueue.global().async { 
     // Begin a new image that will be the new image with the rounded corners 
     // (here with the size of an UIImageView) 
     UIGraphicsBeginImageContextWithOptions(image.size, false, image.scale) 
     let rect = CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height) 

     // Add a clip before drawing anything, in the shape of an rounded rect 
     UIBezierPath(roundedRect: rect, cornerRadius: image.size.width/2).addClip() 

     // Draw your image 
     image.draw(in: rect) 

     // Get the image, here setting the UIImageView image 
     guard let roundedImage = UIGraphicsGetImageFromCurrentImageContext() else { 
      print("UIGraphicsGetImageFromCurrentImageContext failed") 
      completion(nil) 
      return 
     } 

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

     DispatchQueue.main.async { 
      completion(roundedImage) 
     } 
    } 
} 
İlgili konular