This question already has answers here:
IOS: Is possible to rounder radius with different value in each corner
(3 answers)
Closed 4 years ago.
I need to round top corners of a view with any value and also bottom corners of the same view with a different value. Here, I have the code I thought it would solve this. But it doesn't work... Any idea?
bottomPath = UIBezierPath(roundedRect:self.bounds,
byRoundingCorners:[.bottomLeft, .bottomRight],
cornerRadii: CGSize(width: radius, height: radius))
topPath = UIBezierPath(roundedRect:self.bounds,
byRoundingCorners:[.topLeft, .topRight],
cornerRadii: CGSize(width: radius, height: radius))
bottomPath.append(topPath)
maskLayer = CAShapeLayer()
maskLayer?.path = bottomPath.cgPath
self.layer.mask = maskLayer
If I comment bottomPath or topPath I get top or bottom corners rounded, but never both of them
Thank you
I don't believe there is any system call to create a rounded rectangle with different corner radii for each corner. The function UIBezierPath(roundedRect:byRoundingCorners:cornerRadii:) that you are using will create a rounded rectangle with some corners rounded and some not, but the corners you ask to round will all have the same radius.
If you want to create a path with different corners rounded to different radii I'm pretty sure you'll have to build such a path yourself using arcs for each corner and line segments for the flat sides of the rounded rectangle. (You'd draw a closed path composed of an arc with an angle of ∏/2, then a line segment, and repeat that 4 times. The center of each arc would be that corner of the rectangle, inset by the corner radius in both dimensions. It helps to diagram it out on graph paper.)
EDIT:
With a little digging I found this post that includes code to generate a rounded rect with a different corner radius for each corner:
IOS: Is possible to rounder radius with different value in each corner
use the function viewDidLayoutSubviews and call your function inside, to change into round corner.
Example :
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
headerView.roundedButtonForTopRightTopLeft()
view.setNeedsLayout()
view.setNeedsDisplay()
}
extension UIView {
func roundedButtonForTopRightTopLeft(){
let maskPath1 = UIBezierPath(roundedRect: bounds,
byRoundingCorners: [.topRight , .topLeft],
cornerRadii: CGSize(width: 8, height: 8))
let maskLayer1 = CAShapeLayer()
maskLayer1.frame = bounds
maskLayer1.path = maskPath1.cgPath
layer.mask = maskLayer1
}
}
Call after that
override func layoutSubviews() {
//here call round func
self.layoutIfNeeded()
super.layoutSubviews()
}
Related
I'm rounding a UIView with this function:
func roundCorners(_ corners: UIRectCorner, radius: CGFloat) {
let path = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
let mask = CAShapeLayer()
mask.path = path.cgPath
self.layer.mask = mask
}
override func viewDidLoad() {
super.viewDidLoad()
someUIView.roundCorners([.topLeft,.topRight], radius: 20)
}
This works as expected but when testing on iPhone XS Max and All Plus models constraints get messed up, but only on the left side of the screen.
I cant figure out why, i think it has something to do with how the rounded corners function applies a layer on the view beacause when i remove the rounded corners layout is fine even on those iPhone models, or maybe it has to do w/ margins? Idk but i'd really appreciate if someone could help me out w/ this one.
Image so you can appreciate the problem (XS, XSMax, 7, 7+)
You are setting the UIBezierPath using self.bounds before the view is laid out.
Add this to your custom UIView class:
override func layoutSubviews() {
super.layoutSubviews()
self.roundCorners([.topLeft,.topRight], radius: 20)
}
and remove the call from your view controller's viewDidLoad() function.
This question already has answers here:
How to set layer cornerRadius for only bottom-left, bottom-right, and top-left corner?
(13 answers)
Closed 5 years ago.
I need add rounded corner bottom left and right am using UIView above the UIImageView. I have used CAShapeLayer but not cropped as per my requirement. Any solution to achieve this.
Here is how you add rounded corners to your views bottom corners:
let path = UIBezierPath(roundedRect:customView.bounds, byRoundingCorners:[.bottomLeft, .bottomRight], cornerRadii: CGSize(width: 50, height: 50))
let maskLayer = CAShapeLayer()
maskLayer.path = path.cgPath
customView.layer.mask = maskLayer
Final result:
You will of course have to adjust it to your size and colouring.
You could use an extension of you UIView
It's nicely done here
You just have to change it to to :
yourView.roundCorners([.bottomRight, .bottomLeft], radius: YOUR_RADIUS)
I am trying to make UIView topLeft and bottomLeft corners rounded however for some reason only topLeft has border radius. What can cause this?
This is What I am doing:
I have Extension:
extension UIView {
func roundCorners(_ corners: UIRectCorner, radius: CGFloat) {
let path = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
let mask = CAShapeLayer()
mask.path = path.cgPath
self.layer.mask = mask
}
}
And I apply it to view like this:
myView.roundCorners([.topLeft, .bottomLeft], radius: 10.0)
I am using it inside cell and I am also using auto-layout.
At the moment it looks like this(green is the view I am talking about) but I want the bottomLeft to have corner radius also:
The problem is your timing. Your extension relies on self.bounds. But if you call this extension too early, such as viewDidLoad, those bounds have not yet been determined. Your view is sized by auto layout; that means you don't have bounds until your view's layoutSubviews or your view controller's viewDidLayoutSubviews has been called.
I currently have three images next to each other. I combined them into a stack view and would like them to have rounded corners like so:
Instead, after setting the corner radius to each image to 5 I have this:
So my question is how I can make the second picture look like the first one? Keep in mind all three stars are in one stack view.
You can pick corners you want to round with this method for UIView:
extension UIView {
func roundCorners(corners: UIRectCorner, radius: CGFloat) {
let mask = CAShapeLayer()
mask.frame = bounds
mask.path = UIBezierPath(roundedRect: bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height:radius)).cgPath
self.layer.mask = mask
}
}
Usage:
star1.roundCorners(corners: [.topLeft, .bottomLeft], radius: 10)
star3.roundCorners(corners: [.topRight, .bottomRight], radius: 10)
Try out this solution
let path2 = UIBezierPath(roundedRect:view1.bounds, byRoundingCorners:[.TopLeft, .BottomLeft, .TopRight, .BottomRight], cornerRadii: CGSizeMake(20, 20))
let maskLayer2 = CAShapeLayer()
maskLayer2.path = path2.CGPath
view2.layer.mask = maskLayer2
Hope this helps you out.
I put the images behind a view and set the background color to my liking. Then I got rid of any background color for my images. After that, I just rounded the corners of my view.
Here is my problem: I am trying to round the top corners of an UIImageView to look like a UIButton with rounded corner. I am using Masks to do that but the result I have isn't what I am really expecting...
I am using the following extension:
extension UIView
{
func roundCorners(corners:UIRectCorner, radius: CGFloat)
{
let path = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
let mask = CAShapeLayer()
mask.path = path.CGPath
self.layer.mask = mask
}
}
Calling it like this in my code:
imageView.roundCorners([.TopLeft, .TopRight], radius: 80)
And here is the result:
Rounded corners error
I would like to have the top corner to look like the bottom corners (bottom corners are UIButton corners of radius 10) but I don't see where the error is...
Thanks you all for your help !
EDIT: I was using the right code, I just didn't notice that my UIImageView was larger than the UIImage hence the weird corners... I create the UIImageView programmatically and thus didn't notice the size difference... Newbie's mistake...
Thanks you all for you help !
Use this value:
imageView([.TopLeft, .TopRight], radius: 20)