Just two rounded corners?

ipad, iphone, objective-c, rounded-corners

Solution

You have to do this in drawRect:. I actually modified the classic addRoundedRectToPath: so that it takes a bitmap and rounds the corners you request:

static void addRoundedRectToPath(CGContextRef context, CGRect rect, float radius, UIImageRoundedCorner cornerMask)
{
    CGContextMoveToPoint(context, rect.origin.x, rect.origin.y + radius);
    CGContextAddLineToPoint(context, rect.origin.x, rect.origin.y + rect.size.height - radius);
    if (cornerMask & UIImageRoundedCornerTopLeft) {
        CGContextAddArc(context, rect.origin.x + radius, rect.origin.y + rect.size.height - radius, 
                        radius, M_PI, M_PI / 2, 1);
    }
    else {
        CGContextAddLineToPoint(context, rect.origin.x, rect.origin.y + rect.size.height);
        CGContextAddLineToPoint(context, rect.origin.x + radius, rect.origin.y + rect.size.height);
    }

    CGContextAddLineToPoint(context, rect.origin.x + rect.size.width - radius, 
                          rect.origin.y + rect.size.height);

    if (cornerMask & UIImageRoundedCornerTopRight) {
        CGContextAddArc(context, rect.origin.x + rect.size.width - radius, 
                        rect.origin.y + rect.size.height - radius, radius, M_PI / 2, 0.0f, 1);
    }
    else {
        CGContextAddLineToPoint(context, rect.origin.x + rect.size.width, rect.origin.y + rect.size.height);
        CGContextAddLineToPoint(context, rect.origin.x + rect.size.width, rect.origin.y + rect.size.height - radius);
    }

    CGContextAddLineToPoint(context, rect.origin.x + rect.size.width, rect.origin.y + radius);

    if (cornerMask & UIImageRoundedCornerBottomRight) {
        CGContextAddArc(context, rect.origin.x + rect.size.width - radius, rect.origin.y + radius, 
                        radius, 0.0f, -M_PI / 2, 1);
    }
    else {
        CGContextAddLineToPoint(context, rect.origin.x + rect.size.width, rect.origin.y);
        CGContextAddLineToPoint(context, rect.origin.x + rect.size.width - radius, rect.origin.y);
    }

    CGContextAddLineToPoint(context, rect.origin.x + radius, rect.origin.y);

    if (cornerMask & UIImageRoundedCornerBottomLeft) {
        CGContextAddArc(context, rect.origin.x + radius, rect.origin.y + radius, radius, 
                        -M_PI / 2, M_PI, 1);
    }
    else {
        CGContextAddLineToPoint(context, rect.origin.x, rect.origin.y);
        CGContextAddLineToPoint(context, rect.origin.x, rect.origin.y + radius);
    }

    CGContextClosePath(context);
}

This takes a bitmask (I called it UIImageRoundedCorner because I was doing this for images, but you can call it whatever) and then builds up a path based on the corners you want rounded. Then you apply that path to the view in drawRect:

CGContextBeginPath(context);
addRoundedRectToPath(context, rect, radius, yourMask);
CGContextClosePath(context);
CGContextClip(context);

As I said, I was doing this for UIImages, so my code isn't exactly set up for use in drawRect:, but it should be pretty easy to adapt it. You're basically just building up a path and then clipping the context to it.

Edit: To explain the bitmask part, it's just an enum:

typedef enum {
    UIImageRoundedCornerTopLeft = 1,
    UIImageRoundedCornerTopRight = 1 << 1,
    UIImageRoundedCornerBottomRight = 1 << 2,
    UIImageRoundedCornerBottomLeft = 1 << 3
} UIImageRoundedCorner;

In this way you can OR things together to form a bitmask that identifies corners, since each member of the enum represents a different power of two in the bitmask.

Much Later Edit: I've discovered an easier way to do this using `UIBezierPath`'s `bezierPathWithRoundedRect:byRoundingCorners:cornerRadii:`. Just use the bezier path object's `CGPath` in your context.

Problem

In my iPad app, I want a second view to appear within the main when the user clicks a button. The new view will be smaller than the first, and darken the background when it is displayed. I want the top two corners of the new view to appear rounded, but using cornerRadius sets all of them rounded. How can I make just two corners rounded?

Original source

Related problems