UIBezierPath bezierPathWithRoundedRect wrong rounding - ios

I'm trying to round the chat bubbles by applying bezierPathWithRoundedRect to them. Everything works almost perfect. But for some strange reason in some cases one of the corners seems to me much bigger than others. Why it happens and hou to avoid it?
My code:
bubbleContainer.layer.cornerRadius = 6.0;
UIRectCorner cornersOut = (UIRectCornerTopLeft | UIRectCornerTopRight | UIRectCornerBottomLeft);
UIRectCorner cornersIn = (UIRectCornerTopLeft | UIRectCornerTopRight | UIRectCornerBottomRight);
UIRectCorner corners = isOutMessage ? cornersOut : cornersIn;
UIBezierPath * maskPath = [UIBezierPath bezierPathWithRoundedRect:bubbleContainer.bounds byRoundingCorners:corners cornerRadii:CGSizeMake(17.0, 17.0)];
CAShapeLayer * maskLayer = [[CAShapeLayer alloc] init];
maskLayer.frame = bubbleContainer.bounds;
maskLayer.path = maskPath.CGPath;
bubbleContainer.layer.mask = maskLayer;
As you can see, bubbles with text "111" and "1111" have a different top right corner. There is no other masking for bubbles and after applying tha mask bubbles do not resize.

Related

How to curve UIVew only top corner and not whole view in Objective C?

I am new in iOS and I am facing problem regarding to curve UIView. I want to curve the radius of the top of UIView like this in the Image
As you can see the screenshot of my work view.
I am using code like this
UIBezierPath *maskPath = [UIBezierPath
bezierPathWithRoundedRect:ViewSwapMyWork.bounds
byRoundingCorners:(UIRectCornerTopLeft | UIRectCornerTopRight)
cornerRadii:CGSizeMake(70, 70)
];
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.frame = ViewSwapMyWork.bounds;
maskLayer.path = maskPath.CGPath;
ViewSwapMyWork.layer.mask = maskLayer;
First your view should have the same height and width means it should be square, then you can do like this,
[ViewSwapMyWork.layer setCornerRadius:ViewSwapMyWork.frame.size.width/2];
[ViewSwapMyWork.layer setMasksToBounds:YES];

Rounding only left side of UIButton without removing uieffect

I have two uibuttons that a right next to eachother. I would like to make them look joined by giving the left button rounded top left and bottom left corners and the right button top right and bottom right corners.
I have seen several solutions to this but all I have seen break the uieffectview I have behind the button.
You can do it like this:
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.viewOutlet.bounds byRoundingCorners:(UIRectCornerTopLeft | UIRectCornerBottomLeft | UIRectCornerBottomRight) cornerRadii:CGSizeMake(10.0, 10.0)];
CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
maskLayer.frame = self.view.bounds;
maskLayer.path = maskPath.CGPath;
self.viewOutlet.layer.mask = maskLayer;
Update:
If You need border just create another CAShapeLayer and add it to view's layer as sublayer. Like this (place this code below upper code):
CAShapeLayer *borderLayer = [[CAShapeLayer alloc] init];
borderLayer.frame = self.view.bounds;
borderLayer.path = maskPath.CGPath;
borderLayer.lineWidth = 4.0f;
borderLayer.strokeColor = [UIColor blackColor].CGColor;
borderLayer.fillColor = [UIColor clearColor].CGColor;
[self.viewOutlet.layer addSublayer:borderLayer];

Corner by UIBezierPath for flexible View (View can increase width height by content)

I am new in iOS. I am make a chat application. The image below is the table message. In each cell, I set 4 corners for messageView and it display correct
self.messageView.layer.cornerRadius = 10.0;
Now, I want some my message only have 3 corners (top-left, bottom-left, bottom-right) and some message have 3 corners (bottom-left, bottom-right, top-right) - like facebook messenger
so I user UIBezierPath for each cell.
But my message don't display full content.
However, when I scroll up/down, the cell recreate and it displays correct.
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.messageView.bounds byRoundingCorners:(UIRectCornerTopLeft | UIRectCornerBottomLeft | UIRectCornerBottomRight) cornerRadii:CGSizeMake(10.0, 10.0)];
CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
maskLayer.frame = self.bounds;
maskLayer.path = maskPath.CGPath;
self.messageView.layer.mask = maskLayer;
I think my problem is:
When I set the conners by UIBezierPath for my self.messageView, the self.messageView not finished draw yet. so self.messageView.bounds return wrong value.
But I don't know how to fix it.
Any help would be great appreciated
It doesn't seems that you are updating the man in the -layoutSubviews method.
Added layer doesn't know how to deal with your view, so you need to change their size in layoutSubviews of the view that is applying it.
Keep a reference to the mask path and update it, always call super before that.
Try this!!!
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.messageView.bounds byRoundingCorners:(UIRectCornerTopLeft | UIRectCornerBottomLeft | UIRectCornerBottomRight) cornerRadii:CGSizeMake(10.0, 10.0)];
CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
// maskLayer.frame = self.bounds;
maskLayer.frame = self.messageView.bounds; // Try this.
maskLayer.path = maskPath.CGPath;
self.messageView.layer.mask = maskLayer;

Curve-inside UIView top border

I want to curve inside the top border of UIView like this,
I've tried many ways like UIBezierPath etc.
Help needed.
You can do that using UIBezierPath, Have a look at this answer,
UIBezierPath *maskPath;
maskPath = [UIBezierPath bezierPathWithRoundedRect:_backgroundImageView.bounds
byRoundingCorners:(UIRectCornerBottomLeft | UIRectCornerBottomRight)
cornerRadii:CGSizeMake(3.0, 3.0)];
CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
maskLayer.frame = self.bounds;
maskLayer.path = maskPath.CGPath;
_backgroundImageView.layer.mask = maskLayer;
[maskLayer release];
With this we can draw the rounded corners to any side of view.
But If you want to draw rounded edge, Better to take a background image to view.

Minimize off-screen rendering when using CAShapeLayer

Pretty standard setup: VC view has top corners rounded via CAShapeLayer with UIBezierPath, like this:
UIBezierPath *cornerPath = [UIBezierPath bezierPathWithRoundedRect:self.view.bounds
byRoundingCorners:UIRectCornerTopLeft | UIRectCornerTopRight
cornerRadii:CGSizeMake(4, 4)];
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.frame = self.view.bounds;
maskLayer.path = cornerPath.CGPath;
self.view.layer.mask = maskLayer;
While this works, it leads to the whole view being rendered offscreen, surely there should be a way to at least minimize that rendering to corners, or even get rid of it?

Resources