Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to rounded the corners when I draw rectangle using UIBezierPath points

I crated a rectangle using UIBezierPath adding point by point, now I want to rounded the corners of this rectangle but seems there are no way to do it. can anyone help me ?

class RectangleLayer: CAShapeLayer {

    let animationDuration: CFTimeInterval = 0.5

    override init() {
        super.init()
        fillColor = Colors.clear.CGColor
        lineWidth = 5.0
        path = rectanglePathStart.CGPath
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
var rectanglePathStart: UIBezierPath {
        let rectanglePath = UIBezierPath()
        rectanglePath.moveToPoint(CGPoint(x: 0.0, y: 100.0))
        rectanglePath.addLineToPoint(CGPoint(x: 0.0, y: -lineWidth))
        rectanglePath.addLineToPoint(CGPoint(x: 100.0, y: -lineWidth))
        rectanglePath.addLineToPoint(CGPoint(x: 100.0, y: 100.0))
        rectanglePath.addLineToPoint(CGPoint(x: -lineWidth / 2, y: 100.0))

        rectanglePath.closePath()

//        fillColor = Colors.red.CGColor
        return rectanglePath
    }
}
like image 689
roledene JKS Avatar asked Dec 11 '22 18:12

roledene JKS


1 Answers

If all you want to do is create a rounded rectangle, then you can simply use

let rectangle = CGRect(x: 0, y: 0, width: 100, height: 100)
let path = UIBezierPath(roundedRect: rectangle, cornerRadius: 20)

enter image description here

If you want to round some of the corners, but not others, then you can use

let rectangle = CGRect(x: 0, y: 0, width: 100, height: 100)
let path = UIBezierPath(roundedRect: rectangle, byRoundingCorners: [.TopLeft, .BottomRight], cornerRadii: CGSize(width: 35, height: 35))

enter image description here

If you want to have a different corner radius for each corner, then you'll have to add the arc for each circle individually. This comes down to calculating the center and the start and end angle of each arc. You'll find that the center of each arc is inset the corner radius from corresponding corner of the rectangle. For example, the center of the top left corner

CGPoint(x: rectangle.minX + upperLeftRadius, y: rectangle.minY + upperLeftRadius)

The start and end angle for each arc will be either straight left, up, down, or right. The angles corresponding to these directions can be seen in the UIBezierPath documentation.

enter image description here

If you need to create many rectangles like this, you can create a convenience initializer for it

extension UIBezierPath {
    convenience init(roundedRect rect: CGRect, topLeftRadius r1: CGFloat, topRightRadius r2: CGFloat, bottomRightRadius r3: CGFloat, bottomLeftRadius r4: CGFloat) {
        let left  = CGFloat(M_PI)
        let up    = CGFloat(1.5*M_PI)
        let down  = CGFloat(M_PI_2)
        let right = CGFloat(0.0)
        self.init()
        addArcWithCenter(CGPoint(x: rect.minX + r1, y: rect.minY + r1), radius: r1, startAngle: left,  endAngle: up,    clockwise: true)
        addArcWithCenter(CGPoint(x: rect.maxX - r2, y: rect.minY + r2), radius: r2, startAngle: up,    endAngle: right, clockwise: true)
        addArcWithCenter(CGPoint(x: rect.maxX - r3, y: rect.maxY - r3), radius: r3, startAngle: right, endAngle: down,  clockwise: true)
        addArcWithCenter(CGPoint(x: rect.minX + r4, y: rect.maxY - r4), radius: r4, startAngle: down,  endAngle: left,  clockwise: true)
        closePath()
    }
}

And use it like this

let path = UIBezierPath(roundedRect: rectangle, topLeftRadius: 30, topRightRadius: 10, bottomRightRadius: 15, bottomLeftRadius: 5)

enter image description here

like image 76
David Rönnqvist Avatar answered Dec 27 '22 03:12

David Rönnqvist