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?
3 Answers
In Objective C
// Create the path (with only the top-left corner rounded)
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:imageView.bounds
byRoundingCorners:UIRectCornerTopLeft| UIRectCornerTopRight
cornerRadii:CGSizeMake(10.0, 10.0)];
// Create the shape layer and set its path
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.frame = imageView.bounds;
maskLayer.path = maskPath.CGPath;
// Set the newly created shape layer as the mask for the image view's layer
imageView.layer.mask = maskLayer;
This is other to use top rounded corner. Round two corners in UIView
In Swift !!!
myView.clipsToBounds = true
myView.layer.cornerRadius = 10
myView.layer.maskedCorners = [.layerMinXMinYCorner,.layerMaxXMinYCorner]

- 6,401
- 3
- 33
- 39
-
That works, BUT cause offscreen rendering in the entire `imageView` area, resulting in stuttered animation – Philip007 Mar 24 '13 at 17:36
-
Best answer I've found on the subject! – PaperThick Apr 19 '13 at 12:04
-
31@Sachin It's a bit rude to just copy & paste somebody else's answer and pass it off as your own. You could at least put in a link to my original answer: http://stackoverflow.com/a/5826698/429427. – Stuart Jul 03 '13 at 11:52
-
4Cause wrong functionality in autolayaout – jose920405 Jun 04 '15 at 22:40
-
1@jose920405 and I know this answer is old, but I wanted to add that the best way to do this is to use that code in drawRect(rect: CGRect) of the UIView. So, I'd subclass the imageView and implement drawRect and copy that code into the drawRect function (don't forget to call super.drawRect up top!) – David Sep 20 '15 at 09:22
-
`.maskedCorners` is only available on iOS 11. So, if your support platform is as old as iOS 9, then cannot use this solution. – John Pang Nov 29 '18 at 16:23
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.

- 5,207
- 5
- 38
- 54
-
Great answer! Just need a it of help implementing it. First off, how can I make my own bitmask? – Jumhyn Jan 30 '11 at 20:32
-
-
My answer is built to take whatever corners you'd like rounded. If you only need the top two corners and don't care about the others, you could edit the bitmask nonsense out and just use the two sections that correspond to the corners you need rounded. – kevboh Jan 30 '11 at 22:02
-
Ok. Plugged it all in, but no use. The second block of code you gave me with the CGContextBeginPath(context); and such goes in the drawRect: method right? It says that at the line where you create CGRect rect you are redefining rect (since it is the argument for drawRect:). What should I be doing? Also, changing rect's name doesn't do anything. Im sort of confused on how drawRect: actually works, so I'm not too sure about whats wrong. – Jumhyn Jan 30 '11 at 22:42
-
Sorry, my fault for just copying/pasting. drawRect: is what's called when the view is drawn on screen. The argument to drawRect: is the area of the view being drawn. You can just pass that rect directly into addRoundedRectToPath, since you want to round the top two corners of the entire drawn area. I'll edit my answer to remove the rect redefinition as if it were in drawRect:. – kevboh Jan 30 '11 at 23:32
-
-
Are you subclassing UIView directly? If so, you don't need to call super, else you do. And yes, use the current context. – kevboh Jan 30 '11 at 23:42
-
I'm subclassing UINavigationBar. However, it doesnt seem to be working. Am I implementing drawRect correctly? [super drawRect:rect]; CGContextRef context = UIGraphicsGetCurrentContext(); CGContextBeginPath(context); addRoundedRectToPath(context, rect, 50, UINavigationBarRoundedCornerTopRight | UINavigationBarRoundedCornerTopLeft); CGContextClosePath(context); CGContextClip(context); EDIT: Forgot code pasted into comments so horribly. Sorry – Jumhyn Jan 31 '11 at 00:38
The wonderful work done by Tomek Kuźma. Here is the new TKRoundedView class for your requirement.
Your requirement can be fulfill by this parameter only.
TKRoundedView *view = [[TKRoundedView alloc] initWithFrame:frame];
view.roundedCorners = TKRoundedCornerTopLeft | TKRoundedCornerTopRight;
But it also provides following extra features.
TKRoundedView *view = [[TKRoundedView alloc] initWithFrame:frame];
view.roundedCorners = TKRoundedCornerTopLeft
view.borderColor = [UIColor greenColor];
view.fillColor = [UIColor whiteColor];
view.drawnBordersSides = TKDrawnBorderSidesLeft | TKDrawnBorderSidesTop;
view.borderWidth = 5.0f;
view.cornerRadius = 15.0f;
Please checkout the following link for the example project
https://github.com/mapedd/TKRoundedView

- 1,729
- 15
- 23