I typically use the cornerRadius
property to apply rounded corners to view layers. When the views only need rounded top or bottom corners, I apply a mask with a bezier path instead (using bezierPathWithRoundedRect:byRoundingCorners:cornerRadii:
). When both approaches are combined in the same view hierarchy, the rounded corners are not properly aligned, as illustrated below:
This simplified example can be reproduced with the following code:
@interface ViewController : UIViewController
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor blackColor];
CGRect frame = CGRectMake(50.0, 50.0, 100.0, 100.0);
CGFloat radius = 20.0;
// Apply cornerRadius to green backdrop view.
UIView *backdropView = [[UIView alloc] initWithFrame:frame];
backdropView.backgroundColor = [UIColor greenColor];
backdropView.layer.cornerRadius = radius;
[self.view addSubview:backdropView];
// Apply bezier path mask to black front view.
UIView *frontView = [[UIView alloc] initWithFrame:frame];
frontView.backgroundColor = [UIColor blackColor];
CAShapeLayer * maskLayer = [CAShapeLayer layer];
maskLayer.path = [UIBezierPath bezierPathWithRoundedRect:frontView.bounds
byRoundingCorners:UIRectCornerAllCorners
cornerRadii:CGSizeMake(radius, radius)].CGPath;
frontView.layer.mask = maskLayer;
[self.view addSubview:frontView];
}
@end
Setting the shouldRasterize
property of the different layers involved did not solve the issue. I would like to understand why this happens. A possible workaround would be to always apply the bezier path mask rather than simply setting the corner radius but that feels like overkill.
This website does a pretty good job explaining: http://www.paintcodeapp.com/blogpost/code-for-ios-7-rounded-rectangles (in short, it's an iOS7 only thing)
For an extra illustration, see: http://www.mani.de/backstage/?p=483