5

So I have created a button with a border in my storyboard. enter image description here

and then I rounded its corners and added a border color:

button.layer.cornerRadius = button.bounds.size.width / 2
button.layer.borderColor = greenColor

So the runtime result looks like this: enter image description here

However the user can tap slightly outside the area of the button (where the corners used to be) and still call the button function. Is there a way to restrict the enabled area of the button to just be the circle?

LuKenneth
  • 2,197
  • 2
  • 18
  • 41
  • the only way to do what you're asking is to draw a custom shape in code I believe, but sounds like something you shouldn't be too concerned about to be honest. – rigdonmr Jun 03 '16 at 15:09
  • @rigdonmr I figured it out, see my answer if you're curious – LuKenneth Jun 14 '16 at 13:34

3 Answers3

6

With other answers you block the touch, I needed it to fall through. And its even easier:

1) Setup your preferred path (for me circle)

private var touchPath: UIBezierPath {return UIBezierPath(ovalIn: self.bounds)}

2) Override point inside function

override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
    return touchPath.contains(point)
}

All inside you UIButton subclass.

Vojta Rujbr
  • 325
  • 3
  • 11
0

So I figured it out. Basically I have to detect the touch on the button, and then calculate the distance between the touch and the center of the button. If that distance is less than the radius of the circle (the width of the button / 2) then the tap was inside the circle.

Here's my code:

 override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
    let radius:CGFloat = (self.frame.width / 2)
    var point:CGPoint = CGPoint()

    if let touch = touches.first {
        point = touch.locationInView(self.superview)
    }

    let distance:CGFloat = sqrt(CGFloat(powf((Float(self.center.x - point.x)), 2) + powf((Float(self.center.y - point.y)), 2)))

    if(distance < radius) {
        super.touchesBegan(touches, withEvent: event)
    }

}
LuKenneth
  • 2,197
  • 2
  • 18
  • 41
0

(SWIFT 3) This solution works with all the buttons not just with round. Before we have to create path as a private property of the button class and after we can easily write this:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    if let touch = touches.first {
        let location = touch.location(in: self)
        if path.contains(location) {
            print("This print is shown only in case of button location tap")
        }
    }
}
wm.p1us
  • 2,019
  • 2
  • 27
  • 38