Home > other >  How to draw a UIView or a UIButton using UIBezierPath
How to draw a UIView or a UIButton using UIBezierPath

Time:07-02

I want to draw a UIView or a UIButton like this one which is show in the image. enter image description here

How it is possible to draw in swift? I have done a lot of R $ D on this what I get is UIBezierPath. So, How to draw using UIBezierPath. I am unable to draw exactly this. Please help me to draw like this.

I want create a separate class for this so that I can inherit any where.

Thank you in advance.

I have tried something like this.

extension UIButton {
    func roundCorners(corners: UIRectCorner, radius: Int = 8) {
        let maskPath1 = UIBezierPath(roundedRect: bounds,
                                     byRoundingCorners: corners,
                                     cornerRadii: CGSize(width: radius, height: radius))
        
        let maskLayer1 = CAShapeLayer()
        maskLayer1.frame = bounds
        maskLayer1.path = maskPath1.cgPath
        layer.mask = maskLayer1
    }
}

Result is

enter image description here

But I want a sharp cut.Like first image

CodePudding user response:

To draw that shape, you want to use maskPath1.move(to: pt) and then a series of maskPath1.addLine(to: pt).

You'll need six points:

enter image description here

so you could code it like this:

extension UIButton {
    func angledCorners() {
        let maskLayer1 = CAShapeLayer()
        maskLayer1.frame = bounds
        
        let pt1: CGPoint = CGPoint(x: bounds.minX, y: bounds.maxY)
        let pt2: CGPoint = CGPoint(x: bounds.minX, y: bounds.midY)
        let pt3: CGPoint = CGPoint(x: bounds.minX   bounds.midY, y: bounds.minY)
        let pt4: CGPoint = CGPoint(x: bounds.maxX, y: bounds.minY)
        let pt5: CGPoint = CGPoint(x: bounds.maxX, y: bounds.midY)
        let pt6: CGPoint = CGPoint(x: bounds.maxX - bounds.midY, y: bounds.maxY)

        let maskPath1: UIBezierPath = UIBezierPath()
        
        maskPath1.move(to: pt1)
        maskPath1.addLine(to: pt2)
        maskPath1.addLine(to: pt3)
        maskPath1.addLine(to: pt4)
        maskPath1.addLine(to: pt5)
        maskPath1.addLine(to: pt6)
        maskPath1.close()

        maskLayer1.path = maskPath1.cgPath
        layer.mask = maskLayer1
    }
}

A couple problems with that approach though... the mask will not "auto-resize" when the button frame changes. So, you have to wait to call button.angledCorners() until auto-layout has finished setting the button's frame, and you have to call it again any time the frame changes.

If you have explicit frame sizes, that's not a problem.

But if you have buttons that change based on other views, or perhaps change size when the device is rotated, it's a hassle... and you probably want to make this a feature of a custom subclass.

  • Related