17

Hi! I want to draw a rounded corner of my UIView. Only one, others cannot be changed.

Emil Sierżęga
  • 1,785
  • 2
  • 31
  • 38
rooney
  • 171
  • 1
  • 4

4 Answers4

65

Starting in iOS 3.2, you can use the functionality of UIBezierPaths to create an out-of-the-box rounded rect (where only corners you specify are rounded). You can then use this as the path of a CAShapeLayer, and use this as a mask for your view's layer:

// Create the path (with only the top-left corner rounded)
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:imageView.bounds 
                                               byRoundingCorners:UIRectCornerTopLeft
                                                     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;

And that's it - no messing around manually defining shapes in Core Graphics, no creating masking images in Photoshop. The layer doesn't even need invalidating. Applying the rounded corner or changing to a new corner is as simple as defining a new UIBezierPath and using its CGPath as the mask layer's path. The corners parameter of the bezierPathWithRoundedRect:byRoundingCorners:cornerRadii: method is a bitmask, and so multiple corners can be rounded by ORing them together.

NOTE - Layer masks will not render when used in combination with the CALayer renderInContext method. If you need to use this try rounding corners with the following: Just two rounded corners?.

Community
  • 1
  • 1
Stuart
  • 36,683
  • 19
  • 101
  • 139
2

I made a method of StuDev's answer:

+ (CAShapeLayer *) roundedCornerOnImage: (UIImageView *)imageView onCorner: (UIRectCorner)rectCorner
{
    UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:imageView.bounds 
                                                   byRoundingCorners:rectCorner
                                                         cornerRadii:CGSizeMake(10.0, 10.0)];

    CAShapeLayer *maskLayer = [CAShapeLayer layer];
    maskLayer.frame = imageView.bounds;
    maskLayer.path = maskPath.CGPath;

    return maskLayer;
}

Example of usage on a imageview in a UITableViewCell:

if (indexPath.row == 0)
    cell.imageView.layer.mask = [Helper roundedCornerOnImage:cell.imageView onCorner:UIRectCornerTopLeft];
else if (indexPath.row == self.arrayPeople.count - 1)
    cell.imageView.layer.mask = [Helper roundedCornerOnImage:cell.imageView onCorner:UIRectCornerBottomLeft];

Thanks to StuDev for a great solution!

Fernando Redondo
  • 1,557
  • 3
  • 20
  • 38
0
+ (CAShapeLayer *) roundedCornerOnImage: (UIImageView *)imageView onCorner: (UIRectCorner)rectCorner
{
    UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:imageView.bounds 
                                                   byRoundingCorners:rectCorner
                                                         cornerRadii:CGSizeMake(10.0, 10.0)];

    CAShapeLayer *maskLayer = [CAShapeLayer layer];
    maskLayer.frame = imageView.bounds;
    maskLayer.path = maskPath.CGPath;
    imageView.layer.mask=maskLayer
    return maskLayer;
}


if (indexPath.row == 0)
    [Helper roundedCornerOnImage:cell.imageView onCorner:UIRectCornerTopLeft];
else if (indexPath.row == self.arrayPeople.count - 1)
  [Helper roundedCornerOnImage:cell.imageView onCorner:UIRectCornerBottomLeft];

An updated answer to above , you dont need to return and manage that. It can be done in that function.

Ankish Jain
  • 11,305
  • 5
  • 36
  • 34
0

I have made a function for make the Custom corner radius after doing some small R&D as following:

+(void)setConerRadiusForTopLeft:(BOOL)isForTopLeft ForTopRight:(BOOL)isForTopRight ForBottomLeft:(BOOL)isForBottomLeft  ForBottomRight:(BOOL)isForBottomRight withCornerRadius:(float)cornerRadius forView:(UIView *)view
{

    UIRectCorner corners = (isForTopLeft ? UIRectCornerTopLeft : 0) |
                          (isForTopRight ? UIRectCornerTopRight : 0) |
                          (isForBottomLeft ? UIRectCornerBottomLeft : 0) |
                          (isForBottomRight ? UIRectCornerBottomRight : 0);

    UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:view.bounds
                                               byRoundingCorners:corners
                                                     cornerRadii:CGSizeMake(cornerRadius, cornerRadius)];

    CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
    maskLayer.frame = view.bounds;
    maskLayer.path = maskPath.CGPath;
    view.layer.mask = maskLayer;
}
g212gs
  • 863
  • 10
  • 26