circular menu - create menu & call action only if

2019-08-28 23:32发布

I want to create circular menu like below for iPhone app.

enter image description here

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.

enter image description here

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?

标签: ios menu
1条回答
Summer. ? 凉城
2楼-- · 2019-08-29 00:06

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.

查看更多
登录 后发表回答