views:

1966

answers:

3

I can't find anything anywhere(search engines, docs, here, etc) that shows how to create rounded corners (esp. in a grouped table view) on an element that also clips the subviews.

I have code that properly creates a rounded rectangle out of a path with 4 arcs(the rounded corners) that has been tested in the drawRect: method in my subclassed uitableviewcell. The issue is that the subviews, which happen to be uibuttons with their internal uiimageviews, do no obey the CGContextClip() that the uitableviewcell obeys.

Here is the code:

- (void)drawRect:(CGRect)rect
{       
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGFloat radius = 12;
    CGFloat width = CGRectGetWidth(rect);
    CGFloat height = CGRectGetHeight(rect);

    // Make sure corner radius isn't larger than half the shorter side
    if (radius > width/2.0)
        radius = width/2.0;
    if (radius > height/2.0)
        radius = height/2.0;    

    CGFloat minx = CGRectGetMinX(rect) + 10;
    CGFloat midx = CGRectGetMidX(rect);
    CGFloat maxx = CGRectGetMaxX(rect) - 10;
    CGFloat miny = CGRectGetMinY(rect);
    CGFloat midy = CGRectGetMidY(rect);
    CGFloat maxy = CGRectGetMaxY(rect);

    [[UIColor greenColor] set];


    CGContextBeginPath(context);

    CGContextMoveToPoint(context, minx, midy);

    CGContextAddArcToPoint(context, minx, miny, midx, miny, radius);
    CGContextAddArcToPoint(context, maxx, miny, maxx, midy, radius);
    CGContextAddArcToPoint(context, maxx, maxy, midx, maxy, radius);
    CGContextAddArcToPoint(context, minx, maxy, minx, midy, radius);

    CGContextClip(context);
    CGContextFillRect(context, rect);

    [super drawRect:rect];    
}

Because this specific case is static(only shows in 1 specific row of buttons), I can edit the images being used for the buttons to get the desired effect.

HOWEVER, I have another case that is dynamic. Specifically, a grouped table with lots of database-driven results that will show photos that may be in the first or last row with rounded corners and thus needs to be clipped).

So, is it possible to create a CGContextClip() that also clips the subviews? If so, how?

A: 

Create a subclass of UIImageView with rounded corners and transparency. The UITableViewCell itself should be opaque for better performance.

Have a look at this example.

David
A: 

The CALayer object has functions for rounding corners:

UIView * someview = something here;
CALayer * layer = [someview layer];
layer.masksToBounds = YES;
layer.cornerRadius = radius;

And you're all set. You can also add some border colors and stuff, check out the docs in case you're interested.

Nick
You should never use CALayer's cornerRadius inside a UITableViewCell. Its performance hit is much too great for the speed that such cells must be drawn to have a fast scrolling table.
Sbrocket
There is no way to use this for tablecells as the cornerRadius setting is for all corners. There is no way to make a rounded-top only cell
coneybeare
+1  A: 

See this code: http://gist.github.com/292384

I've used it in multiple projects, the performance is great and it's highly customizable. It doesn't use cornerRadius and the drawing of the cells is context-sensitive.

Cirrostratus
Ooh, I'm not sure that code addresses your subviews query though. Useful code for context-sensitive rounded group-style tables nonetheless.
Cirrostratus