0

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

frndev
  • 82
  • 1
  • 10
  • This answer has a good `UIBezierPath` extension that will allow you to set different radii for each corner... https://stackoverflow.com/a/43651478/6257435 – DonMag Jun 11 '18 at 12:55
  • Appending 2 paths with different corner radii will not give you what you want. See my answer. It includes a link to a thread that shows how create the path you need. – Duncan C Jun 11 '18 at 13:09

3 Answers3

0

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
        }
}
Osman
  • 1,496
  • 18
  • 22
  • That will round 2 of 4 corners, but won't give the effect the OP is after (all 4 corners rounded, but with a different radius for top and bottom corners. – Duncan C Jun 11 '18 at 15:56
0

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

Community
  • 1
  • 1
Duncan C
  • 128,072
  • 22
  • 173
  • 272
-1

Call after that

override func layoutSubviews() {
//here call round func 
self.layoutIfNeeded()
super.layoutSubviews()

}
Anbu.Karthik
  • 82,064
  • 23
  • 174
  • 143
Sheraz
  • 1
  • 1
  • 1