Search code examples
xcodeswiftuibuttonframecgrect

How to make the frame of a button custom shape in Swift 2


I want the button to be reactive to tap only in the custom polygonal shape that I create and not in the CGRect frame.

button.frame only supports CGRect.


Solution

  • Here is an example of a button that only responds to touches within a certain area.

    enter image description here

    class MyButton: UIButton {
    
        var path: UIBezierPath!
    
        override func awakeFromNib() {
            backgroundColor = UIColor.greenColor()
            addTarget(self, action: #selector(touchDown), forControlEvents: .TouchDown)
        }
        override func drawRect(rect: CGRect) {
            path = UIBezierPath()
    
            path.moveToPoint(CGPointMake(150, 10))
            path.addLineToPoint(CGPointMake(200, 10))
            path.addLineToPoint(CGPointMake(150, 100))
            path.addLineToPoint(CGPointMake(100, 100))
            path.closePath()
    
            let shapeLayer = CAShapeLayer()
            shapeLayer.strokeColor = UIColor.redColor().CGColor
            shapeLayer.fillColor = UIColor.blueColor().CGColor
            shapeLayer.path = path.CGPath
            layer.addSublayer(shapeLayer)
    
        }
    
        func touchDown(button: MyButton, event: UIEvent) {
            if let touch = event.touchesForView(button)?.first {
                let location = touch.locationInView(button)
    
                if path.containsPoint(location) == false {
                    button.cancelTrackingWithEvent(nil)
                }
            }
    
        }
    }