Search code examples
ioslayeruibezierpath

IOS: Is possible to rounder radius with different value in each corner


I want to rounder my UIView with the value like that
top-left-radius:20; bottom-right-radius:5; bottom-left-radius:5; and top-right-radius:10;

   //For rounder `UIRectCornerBottomLeft & UIRectCornerBottomRight` I use

    UIBezierPath *maskPath0 = [UIBezierPath bezierPathWithRoundedRect:self.messageView.bounds byRoundingCorners:(UIRectCornerBottomLeft | UIRectCornerBottomRight) cornerRadii:CGSizeMake(5.0, 5.0)];

    CAShapeLayer *maskLayer0 = [[CAShapeLayer alloc] init];
    maskLayer0.frame = self.bounds;
    maskLayer0.path  = maskPath0.CGPath;
    self.messageView.layer.mask = maskLayer0;


    //For rounder `TopRight` I use

    UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.messageView.bounds byRoundingCorners:(UIRectCornerTopRight) cornerRadii:CGSizeMake(10.0, 10.0)];

    CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
    maskLayer.frame = self.bounds;
    maskLayer.path  = maskPath.CGPath;
    self.messageView.layer.mask = maskLayer;


    //For rounder `TopLeft` I use

    UIBezierPath *maskPath2 = [UIBezierPath bezierPathWithRoundedRect:self.messageView.bounds byRoundingCorners:(UIRectCornerTopLeft) cornerRadii:CGSizeMake(20.0, 20.0)];

    CAShapeLayer *maskLayer2 = [[CAShapeLayer alloc] init];
    maskLayer2.frame = self.bounds;
    maskLayer2.path  = maskPath2.CGPath;
    self.messageView.layer.mask = maskLayer2;

But the result I get is the View with corner radius TopLeft with value 20. How can I achieve this rounder? Any help would be much appreciated.


Solution

  • UIBezierPath has no such method. But you can use bunch of addLineToPoint and addArcWithCenter methods to do it:

    let minx = CGRectGetMinX(rect)
    let miny = CGRectGetMinY(rect)
    let maxx = CGRectGetMaxX(rect)
    let maxy = CGRectGetMaxY(rect)
    
    let path = UIBezierPath()
    path.moveToPoint(CGPointMake(minx + topLeftRadius, miny))
    path.addLineToPoint(CGPointMake(maxx - topRightRadius, miny))
    path.addArcWithCenter(CGPointMake(maxx - topRightRadius, miny + topRightRadius), radius: topRightRadius, startAngle:3 * M_PI_2, endAngle: 0, clockwise: true)
    path.addLineToPoint(CGPointMake(maxx, maxy - bottomRightRadius))
    path.addArcWithCenter(CGPointMake(maxx - bottomRightRadius, maxy - bottomRightRadius), radius: bottomRightRadius, startAngle: 0, endAngle: M_PI_2, clockwise: true)
    path.addLineToPoint(CGPointMake(minx + bottomLeftRadius, maxy))
    path.addArcWithCenter(CGPointMake(minx + bottomLeftRadius, maxy - bottomLeftRadius), radius: bottomLeftRadius, startAngle: M_PI_2, endAngle: M_PI, clockwise: true)
    path.addLineToPoint(CGPointMake(minx, miny + topLeftRadius))
    path.addArcWithCenter(CGPointMake(minx + topLeftRadius, miny + topLeftRadius), radius: topLeftRadius, startAngle: M_PI, endAngle: 3 * M_PI_2, clockwise: true)
    path.closePath()
    

    For Obj-C:

    CGFloat topLeftRadius = 20;
    CGFloat topRightRadius = 10;
    CGFloat bottomRightRadius = 5;
    CGFloat bottomLeftRadius = 5;
    
    CGFloat minx = CGRectGetMinX(self.messageView.bounds);
    CGFloat miny = CGRectGetMinY(self.messageView.bounds);
    CGFloat maxx = CGRectGetMaxX(self.messageView.bounds);
    CGFloat maxy = CGRectGetMaxY(self.messageView.bounds);
    
    UIBezierPath *path = [[UIBezierPath alloc] init];
    [path moveToPoint:CGPointMake(minx + topLeftRadius, miny)];
    [path addLineToPoint:CGPointMake(maxx - topRightRadius, miny)];
    [path addArcWithCenter:CGPointMake(maxx - topRightRadius, miny + topRightRadius) radius: topRightRadius startAngle: 3 * M_PI_2 endAngle: 0 clockwise: YES];
    [path addLineToPoint:CGPointMake(maxx, maxy - bottomRightRadius)];
    [path addArcWithCenter:CGPointMake(maxx - bottomRightRadius, maxy - bottomRightRadius) radius: bottomRightRadius startAngle: 0 endAngle: M_PI_2 clockwise: YES];
    [path addLineToPoint:CGPointMake(minx + bottomLeftRadius, maxy)];
    [path addArcWithCenter:CGPointMake(minx + bottomLeftRadius, maxy - bottomLeftRadius) radius: bottomLeftRadius startAngle: M_PI_2 endAngle:M_PI clockwise: YES];
    [path addLineToPoint:CGPointMake(minx, miny + topLeftRadius)];
    [path addArcWithCenter:CGPointMake(minx + topLeftRadius, miny + topLeftRadius) radius: topLeftRadius startAngle: M_PI endAngle:3 * M_PI_2 clockwise: YES];
    [path closePath];
    
    CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
    maskLayer.path = path.CGPath;
    self.messageView.layer.mask = maskLayer;