Using cornerRadius on a UIImageView in a UITableViewCell

前端 未结 4 1091
情歌与酒
情歌与酒 2021-01-31 11:55

I\'m using a UIImageView for each of my UITableViewCells, as thumbnails. My code uses SDWebImage to asynchronously grab those images from

相关标签:
4条回答
  • 2021-01-31 12:11

    Non blocking solution

    As a follow up to Andrea's response, here is a function that will run his code in the background.

    + (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 讨论(0)
  • 2021-01-31 12:19

    Swift 3 version of thedeveloper3124's answer

    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)
            }
        }
    }
    
    0 讨论(0)
  • 2021-01-31 12:28

    Yes, that's because cornerRadius and clipToBounds requires offscreen rendering, I suggest you to read these answer from one of my question. I also quote two WWDC session thatyou should see.
    The best thing you can do is grab the image right after is downloaded and on another thread dispatch a method that round the images. Is preferable that you work on the image instead of the imageview.

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

    Method grabbed here You can also subclass the tableviewcell and override the drawRect method.
    The dirty but very effective way is draw a mask in photoshop with inside alpha and around the matching color of the background of the cell and add another imageView, not opaque with clear background color, on the one with images.

    0 讨论(0)
  • 2021-01-31 12:28

    There is another good solution for this. I did it a few times in my projects. If you want to create a rounded corners or something else you could just use a cover image in front of your main image.

    For example, you want to make rounded corners. In this case you need a square image layer with a cut out circle in the center.

    By using this method you will get 60fps on scrolling inside UITableView or UICollectionView. Because this method not required offscreen rendering for customizing UIImageView's (like avatars and etc.).

    0 讨论(0)
提交回复
热议问题