Create clickable body diagram with Swift (iOS)

我的梦境 提交于 2019-11-29 07:36:28

There is no built-in mechanism for detecting taps in irregular shapes. The standard UIView tap detection uses frame rectangles. (Likewise with CALayers, as suggested by sketchyTech in his comment above.)

I would suggest drawing your body regions as bezier paths. You could create a custom subclass of UIView (BodyView) that would manage an array of BodyRegion objects each of which include a bezier path.

The UIBezierPath class includes a method containsPoint that lets you tell if a point is inside the path. Your BodyView could us that to decide which path object was tapped.

Bezier paths would handle both drawing your body regions and figuring out which part was tapped.

A very simple way to achieve this, would be to place invisible buttons over the areas, then hook every one up to an IBAction and put anything you want to happen inside.

@IBAction func shinTapped(sender: UIButton) {
    tappedCounter = 0
    if tappedCounter == 0 {
      // set property to keep track
      shinSelected = true
      // TODO: set button image to selected state
      // increment counter
      tappedCounter++
      }else{
      // set property to keep track
      shinSelected = false
      // TODO: set button image to nil
      // reset counter
      tappedCounter = 0
  }

This might get a little tricky to layout, so that every button sits in the right spot, but if you work with size classes it is totally doable. I am sure there is a more elegant way to do it, but this is one way.

Fixed!

First I added sublayers to the UIImageView like this

var path = UIBezierPath()
path.moveToPoint(CGPointMake(20, 30))
path.addLineToPoint(CGPointMake(40, 30))

// add as many coordinates you need...

path.closePath()

var layer = CAShapeLayer()
layer.path = path.CGPath
layer.fillColor = UIColor(red: 255, green: 0, blue: 0, alpha: 0.5).CGColor
layer.hidden = true

bodyImage.layer.addSublayer(layer)

Than I overrided the touchesbegan function in order to show and hide when the shapes are tapped.

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {

    if let touch = touches.first! as? UITouch {
        // get tapped position
        let position = touch.locationInView(self.bodyImage)

        // loop all sublayers
        for layer in self.bodyImage.layer.sublayers! as! [CAShapeLayer] {

            // check if tapped position is inside shape-path
            if CGPathContainsPoint(layer.path, nil, position, false) {
                if (layer.hidden) {
                    layer.hidden = false
                }
                else {
                    layer.hidden = true
                }
            }
        }
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!