3
votes

I'm Trying to round my view's corners using "UIBezierPath". I Only need to round topRight and Top left.

I have used Following code

 -(void)setMaskOnView:(UIView *)givenView
  {
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:givenView.bounds byRoundingCorners: (UIRectCornerTopLeft|UIRectCornerTopRight) cornerRadii:CGSizeMake(10.0, 10.0)];
CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
maskLayer.frame = givenView.bounds;
maskLayer.path  = maskPath.CGPath;
givenView.layer.mask = maskLayer;
} 

enter image description here

But my TopRight Corner does not round.

I've used

UIRectCornerAllCorners

But it does not round my right corners

enter image description here

Any thing i'm missing??

2
Where do you call setMaskOnView? Probably before the layout did complete. Therefore the bounds are not correctly set yet and will / do change. - luk2302
givenView.bounds changed to givenView.superview.bounds and check if work - Parth Bhadaja
@luk2302 i call it in viewDidLoad - Arslan Asim
There you go - that is the wrong place, you have to set the mask whenever the layout changes. - luk2302
But why left one's were rounding?? - Arslan Asim

2 Answers

1
votes

I suggest different approach. Load image with rounded top corners and set is as contents of CALayer. Set this layer as mask of your view layer. Update size of your mask layer in layoutSubivews of a given view or viewDidLayoutSubviews of given view controller.

Loading image as layer contenst

CALayer *maskLayer = [[CALayer alloc] init];
UIImage *maskImage = [UIImage imageNamed:@"mask_image.png" inBundle:[NSBundle mainBundle] compatibleWithTraitCollection:nil];
maskLayer.contents = (__bridge id _Nullable)(maskImage.CGImage);

mainLayer.mask = maskLayer

[EDIT] Answering your questions in comments

Either using CAShapeLayer or image as mask you have to resize your mask layer so it will have the same size as masked layer. If we are talking about UITableViewCell create your own derived cell and update mask shape in layoutSubviews . Below is example code (MyTableCell is loaded from storyboard):

@interface MyTableCell ()

@property (nonatomic, strong) CAShapeLayer *maskLayer;

@end

@implementation MyTableCell

- (void)awakeFromNib
{
    self.maskLayer = [[CAShapeLayer alloc] init];
    self.layer.mask = self.maskLayer;
}

- (void)layoutSubviews
{
    [super layoutSubviews];
    self.maskLayer.path = [self maskPath].CGPath;
}

- (UIBezierPath *)maskPath
{
    return [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners: (UIRectCornerTopLeft|UIRectCornerTopRight) cornerRadii:CGSizeMake(10.0, 10.0)];

}

@end
0
votes

I'm using this subclass

.h

@interface UIView (custom)

- (UIView *)setRoundedCorners:(UIRectCorner)corners withRadius:(CGFloat)radius;

@end

.m

@implementation UIView (custom)

    - (UIView *)setRoundedCorners:(UIRectCorner)corners withRadius:(CGFloat)radius
    {
        UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.bounds
                                                       byRoundingCorners:corners
                                                             cornerRadii:CGSizeMake(radius, radius)];

        CAShapeLayer *maskLayer = [CAShapeLayer layer];

        maskLayer.frame = self.bounds;

        maskLayer.path = maskPath.CGPath;

        self.layer.mask = maskLayer;

        return self;
    }
@end

Using it like:

[YOURVIEW setRoundedCorners:UIRectCornerBottomLeft | UIRectCornerBottomRight | UIRectCornerTopLeft | UIRectCornerTopRight withRadius:15];