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.
Related
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];
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];
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;
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?
I am trying to round the bottom two corners of a UIView, and have the layer’s border show up rounded as well. I am currently doing:
UIRectCorners corners = UIRectCornerBottomLeft | UIRectCornerBottomRight;
CGSize radii = CGSizeMake(kThisViewCornerRadius, kThisViewCornerRadius);
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:myView.bounds
byRoundingCorners:corners
cornerRadii:radii];
CAShapeLayer *maskLayer = [CAShapeLayer layer];
[maskLayer setPath:path.CGPath];
myView.layer.mask = maskLayer;
This works fine for normal views. However, myView’s layer has its borderColor and borderWidth set, and as you can see from the screenshot, the layer’s border is not getting rounded:
I also tried subclassing UIView and returning [CAShapeLayer layer] from +[Class layerClass], and setting up the view’s layer as a shape layer, but the border ended up beneath the view’s subviews.
Is it possible to round some of a view’s corners, round the view’s layer’s border, and clip the subviews underneath the layer’s border?
Note that this is not about how to round some corners and not others, but rather how to get the stroke to behave correctly.
I figured out a new way of thinking about it, thanks to David Rönnqvist’s comment.
I was trying to do the corner rounding and the stroke all in one layer. Instead, I broke it up into two layers: one to mask the view’s layer to round the corners, and the other in a view to add the stroke.
UIView *containerView = [[UIView alloc] initWithFrame:someFrame];
UIRectCorners corners = UIRectCornerBottomLeft | UIRectCornerBottomRight;
CGSize radii = CGSizeMake(kThisViewCornerRadius, kThisViewCornerRadius);
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:myView.bounds
byRoundingCorners:corners
cornerRadii:radii];
// Mask the container view’s layer to round the corners.
CAShapeLayer *cornerMaskLayer = [CAShapeLayer layer];
[cornerMaskLayer setPath:path.CGPath];
containerView.layer.mask = cornerMaskLayer;
// Make a transparent, stroked layer which will dispay the stroke.
CAShapeLayer *strokeLayer = [CAShapeLayer layer];
strokeLayer.path = path.CGPath;
strokeLayer.fillColor = [UIColor clearColor].CGColor;
strokeLayer.strokeColor = [UIColor redColor].CGColor;
strokeLayer.lineWidth = 2; // the stroke splits the width evenly inside and outside,
// but the outside part will be clipped by the containerView’s mask.
// Transparent view that will contain the stroke layer
UIView *strokeView = [[UIView alloc] initWithFrame:containerView.bounds];
strokeView.userInteractionEnabled = NO; // in case your container view contains controls
[strokeView.layer addSublayer:strokeLayer];
// configure and add any subviews to the container view
// stroke view goes in last, above all the subviews
[containerView addSubview:strokeView];
Zev Eisenberg's answer is the right one.
Although I prefer:
[self.layer addSublayer:strokeLayer];
instead of creating and adding a subview:
CGSize radii = CGSizeMake(radius, radius);
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:self.bounds
byRoundingCorners:corners
cornerRadii:radii];
// Mask the container view’s layer to round the corners.
CAShapeLayer *cornerMaskLayer = [CAShapeLayer layer];
[cornerMaskLayer setPath:path.CGPath];
self.layer.mask = cornerMaskLayer;
// Make a transparent, stroked layer which will dispay the stroke.
CAShapeLayer *strokeLayer = [CAShapeLayer layer];
strokeLayer.path = path.CGPath;
strokeLayer.fillColor = [UIColor clearColor].CGColor;
strokeLayer.strokeColor = color.CGColor;
strokeLayer.lineWidth = 2; // the stroke splits the width evenly inside and outside,
// but the outside part will be clipped by the containerView’s mask.
[self.layer addSublayer:strokeLayer];
Here is the small code. Alloc init a view and send to this method to get corners rounded. You can optionally round any of the corners u want. Also give shadow stroke color.
-(void) setMaskTo:(UIView*)view byRoundingCorners:(UIRectCorner)corners withColor: (UIColor*) color
{
UIBezierPath* rounded = [UIBezierPath bezierPathWithRoundedRect:view.bounds byRoundingCorners:corners cornerRadii:CGSizeMake(9.0, 9.0)];
CAShapeLayer* shape = [[[CAShapeLayer alloc] init] autorelease];
[shape setPath:rounded.CGPath];
shape.strokeColor = [[UIColor grayColor] CGColor];
view.backgroundColor=color;
view.layer.mask = shape;
}
Call the method like this.
[self setMaskTo:ABCView byRoundingCorners:UIRectCornerAllCorners withColor:[UIColor greenColor]];