How do I add a UIImage to grouped UITableViewCell so it rounds the corners?

后端 未结 5 710
囚心锁ツ
囚心锁ツ 2021-02-14 14:38

I\'m trying to add images to table cells in a grouped UITableView but the corners of the images are not clipped. What\'s the best way to go about clipping these (besides clippin

相关标签:
5条回答
  • 2021-02-14 14:58

    There isn't a built-in standard way to do this, but it's not terribly hard to do in your own code. There are examples on how to round corners on an UIImage on the web, see for example http://blog.sallarp.com/iphone-uiimage-round-corners/.

    0 讨论(0)
  • 2021-02-14 15:00

    There is built-i way if you want to just display the rounded corners. Put the image in a UIImageView and then set the cornerRadius of the layer of the UIImageView. You will also need to tell the UIImageView to clip to bounds but that will give you rounded corners.

    UIImageView *myImageView = [[UIImageView alloc] initWithImage:...];
    [myImageView setClipsToBounds:YES];
    [[myImageView layer] setCornerRadius:5.0f];
    
    0 讨论(0)
  • 2021-02-14 15:09

    A couple additions/changes, hope it helps someone:

    1) roundTop and roundBottom impl changed slightly.

    2) made a class method in separate class so reuse is easier, rather than copy/paste everywhere.

    First, the new class details:

    #import <Foundation/Foundation.h>
    #import <QuartzCore/QuartzCore.h>
    
    @interface RoundedImages : NSObject {
    }
    +(UIImage *)roundCornersOfImage:(UIImage *)source roundTop:(BOOL)top roundBottom:(BOOL)bottom;
    @end
    

    And its implementation:

    #import "RoundedImages.h"
    
    @implementation RoundedImages
    
    void addRoundedRectToPath(CGContextRef context, CGRect rect, float ovalWidth, float ovalHeight, BOOL top, BOOL bottom)
    {
        float fw, fh;
        if (ovalWidth == 0 || ovalHeight == 0) {
            CGContextAddRect(context, rect);
            return;
        }
        CGContextSaveGState(context);
        CGContextTranslateCTM (context, CGRectGetMinX(rect), CGRectGetMinY(rect));
        CGContextScaleCTM (context, ovalWidth, ovalHeight);
        fw = CGRectGetWidth (rect) / ovalWidth;
        fh = CGRectGetHeight (rect) / ovalHeight;
        CGContextMoveToPoint(context, fw, fh/2);
    
        if (top) {
            CGContextAddArcToPoint(context, fw, fh, fw/2, fh, 3);
            CGContextAddArcToPoint(context, 0, fh, 0, fh/2, 3);
            CGContextAddArcToPoint(context, 0, 0, fw/2, 0, 0);
            CGContextAddArcToPoint(context, fw, 0, fw, fh/2, 0);
        } else {
            CGContextAddArcToPoint(context, fw, fh, fw/2, fh, 0);
            CGContextAddArcToPoint(context, 0, fh, 0, fh/2, 0);
            CGContextAddArcToPoint(context, 0, 0, fw/2, 0, 3);
            CGContextAddArcToPoint(context, fw, 0, fw, fh/2, 3);
        }
    
        CGContextClosePath(context);
        CGContextRestoreGState(context);
    }
    
    +(UIImage *)roundCornersOfImage:(UIImage *)source roundTop:(BOOL)top roundBottom:(BOOL)bottom {
        int w = source.size.width;
        int h = source.size.height;
    
        CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
        CGContextRef context = CGBitmapContextCreate(NULL, w, h, 8, 4 * w, colorSpace, kCGImageAlphaPremultipliedFirst);
    
        CGContextBeginPath(context);
        CGRect rect = CGRectMake(0, 0, w, h);
        //addRoundedRectToPath(context, rect, 4, 4, top, bottom);
        addRoundedRectToPath(context, rect, 5, 5, top, bottom);
        CGContextClosePath(context);
        CGContextClip(context);
    
        CGContextDrawImage(context, CGRectMake(0, 0, w, h), source.CGImage);
    
        CGImageRef imageMasked = CGBitmapContextCreateImage(context);
        CGContextRelease(context);
        CGColorSpaceRelease(colorSpace);
    
        //return [UIImage imageWithCGImage:imageMasked];
        UIImage *image = [UIImage imageWithCGImage:imageMasked]; 
        CGImageRelease(imageMasked);
        return image;
    }
    
    @end
    

    To use in another class (eg, view controller):

    #import "RoundedImages.h"
    

    ...and later we use it like this...

    UIImageView *imageView = nil;
        UIImage *img = [UIImage imageNamed:@"panel.png"];
    
        if (indexPath.row == 0) {
            imageView = [[UIImageView alloc]initWithImage:[RoundedImages roundCornersOfImage:img roundTop:YES roundBottom:NO]];
        }
        else if (indexPath.row == ([choices count]-1))
        {
            imageView = [[UIImageView alloc]initWithImage:[RoundedImages roundCornersOfImage:img roundTop:NO roundBottom:YES]];
        }
        else {
            imageView = [[UIImageView alloc]initWithImage:img];
        }
        cell.backgroundColor = [UIColor clearColor];
        imageView.clipsToBounds = NO;
        cell.backgroundView = imageView;
        cell.backgroundView = [[UIView alloc] initWithFrame:CGRectZero];
        [cell.backgroundView addSubview:imageView];
        [imageView release];
    

    Note that the "choices" above was just a mutable array I was using on this page that contained the data for the tableview.

    I should add that the usage snippet above is used inside your cellForRowAtIndexPath method, and "cell" is a uitableviewcell.

    Anyway, works like a champ for me.

    0 讨论(0)
  • 2021-02-14 15:10

    If you're happy to have all four image corners rounded, then you can just do the following when creating the cell:

    cell.imageView.layer.masksToBounds = YES;
    cell.imageView.layer.cornerRadius = 10.0;
    

    If you also want to inset the image from the boundary, I described a simple category on UIImage to do it here.

    0 讨论(0)
  • 2021-02-14 15:12

    This was my solution, which could use a little refactoring:

    void addRoundedRectToPath(CGContextRef context, CGRect rect, float ovalWidth, float ovalHeight, BOOL top, BOOL bottom)
    {
        float fw, fh;
        if (ovalWidth == 0 || ovalHeight == 0) {
            CGContextAddRect(context, rect);
            return;
        }
        CGContextSaveGState(context);
        CGContextTranslateCTM (context, CGRectGetMinX(rect), CGRectGetMinY(rect));
        CGContextScaleCTM (context, ovalWidth, ovalHeight);
        fw = CGRectGetWidth (rect) / ovalWidth;
        fh = CGRectGetHeight (rect) / ovalHeight;
        CGContextMoveToPoint(context, fw, fh/2);
        CGContextAddArcToPoint(context, fw, fh, fw/2, fh, 0);
    
        NSLog(@"bottom? %d", bottom);
    
        if (top) {
            CGContextAddArcToPoint(context, 0, fh, 0, fh/2, 3);
        } else {
            CGContextAddArcToPoint(context, 0, fh, 0, fh/2, 0);
        }
    
        if (bottom) {
            CGContextAddArcToPoint(context, 0, 0, fw/2, 0, 3);
        } else {
            CGContextAddArcToPoint(context, 0, 0, fw/2, 0, 0);
        }
    
        CGContextAddArcToPoint(context, fw, 0, fw, fh/2, 0);
        CGContextClosePath(context);
        CGContextRestoreGState(context);
    }
    
    - (UIImage *)roundCornersOfImage:(UIImage *)source roundTop:(BOOL)top roundBottom:(BOOL)bottom {
        int w = source.size.width;
        int h = source.size.height;
    
        CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
        CGContextRef context = CGBitmapContextCreate(NULL, w, h, 8, 4 * w, colorSpace, kCGImageAlphaPremultipliedFirst);
    
        CGContextBeginPath(context);
        CGRect rect = CGRectMake(0, 0, w, h);
        addRoundedRectToPath(context, rect, 4, 4, top, bottom);
        CGContextClosePath(context);
        CGContextClip(context);
    
        CGContextDrawImage(context, CGRectMake(0, 0, w, h), source.CGImage);
    
        CGImageRef imageMasked = CGBitmapContextCreateImage(context);
        CGContextRelease(context);
        CGColorSpaceRelease(colorSpace);
    
        return [UIImage imageWithCGImage:imageMasked];    
    }
    

    Implement those functions, then check the indexPath in the cellForRowAtIndexPath delegate method to determine which corner to round.

    if (indexPath.row == 0) {
                cell.imageView.image = [self roundCornersOfImage:coverImage roundTop:YES roundBottom:NO];
            } else if (indexPath.row == [indexPath length]) {
                cell.imageView.image = [self roundCornersOfImage:coverImage roundTop:NO roundBottom:YES];
            } else {
                cell.imageView.image = coverImage;
            }
    
    0 讨论(0)
提交回复
热议问题