I want to create circular menu like below for iPhone app.
I searched many libraries or solutions, however was unable to find the same. What all have is when they click on icon, menu action is called, however I want to call action if I click anywhere on the button as shown below.
User action will only get called if I click anywhere in the user of user as shown in above image.
Any idea how to achieve this?
I have one idea as checking the x & y position of the tap and findout where its clicked (but this is very time costly)
OR
Is there any way to create buttons of these shapes?
I have one idea as checking the x & y position of the tap and findout
where its clicked (but this is very time costly)
That's actually a very good idea, and the calculations are not very costly at all.
// Function to compute button touched
//
// Returns:
// 0 - 7: One of the 8 outer buttons touched
// 8: Center button touched
// 9: Touch outside of outer circle (no button touched)
func detectTouchedButton(_ touchPoint: CGPoint) -> Int {
// Set these values for your situation:
let innerRadius: CGFloat = 50
let outerRadius: CGFloat = 150
let center = CGPoint(x: 150, y: 200)
// Compute horizontal and vertical distance of touch from center
let dx = touchPoint.x - center.x
let dy = center.y - touchPoint.y
// was the center button touched?
let distanceSquared = dx * dx + dy * dy
if distanceSquared < innerRadius * innerRadius {
return 8
}
// was touch outside of outer circle?
if distanceSquared > outerRadius * outerRadius {
return 9
}
// Use atan2 to get an angle between -.pi and
// .pi. Divide by .pi to get number in the range
// of (-1...1). Add 1 to get a range of (0...2).
// Multiply by 4 to get a range of (0...8). Mod
// by 8 since 0 == 8 (same button)
return Int(4 * (atan2(dy, dx) / .pi + 1)) % 8
}
Notes:
I flipped the dy
calculation because the coordinate system is upside down. This just returns the coordinate system to the +y
is up mathematical sense and changes the final ordering of 0
through 7
.
If you wanted, you could modify this to return an Int?
and then return nil
for touches that aren't on a button.