使用 Swift (iOS) 创建可点击的 body 图表

Create clickable body diagram with Swift (iOS)

我正在尝试为 iOS 应用 (Swift) 重新创建一些内容,我已经在 HTML5(使用 map area-coords)。

我想展示一个与用户 clicks/touches 交互的人类 body 图。 body 存在比方说 20 个不同的部分,用户可以 select 一个或多个 body-parts。对于每个 body-part 都有一个 selected-state 图像,当一个部分被 selected 时应该出现。单击 select 编辑的部分将取消 select 它。在 select 完成一个或多个部分后,用户可以继续并在下一个 viewcontroller 中获得有关这些部分的一些信息。我附上一张简化的图片来解释我的目标。

能否有人body 解释实现此目标的最佳方法是什么?在 Swift 中是否有类似的技术可以用来创建这样的交互式图像?

谢谢!

没有 built-in 机制来检测不规则形状的敲击。标准的 UIView 点击检测使用框架矩形。 (与 CALayers 一样,正如 sketchyTech 在他上面的评论中所建议的那样。)

我建议将您的 body 区域绘制为贝塞尔曲线路径。您可以创建一个 UIView (BodyView) 的自定义子class,它将管理一个 BodyRegion object 数组,每个包含一个贝塞尔曲线路径。

UIBezierPath class 包含一个方法 containsPoint,它可以让您判断一个点是否在路径内。您的 BodyView 可以让我们决定 object 哪条路径被窃听了。

Bezier 路径将处理绘制您的 body 区域 以确定哪个部分被点击。

实现此目的的一种非常简单的方法是在区域上放置不可见按钮,然后将每个按钮连接到 IBAction 并将您想要发生的任何内容放入其中。

@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
  }

这在布局上可能有点棘手,因此每个按钮都位于正确的位置,但如果您使用 类 大小,则完全可行。 我相信有一种更优雅的方式来做到这一点,但这是一种方式。

已修复!

首先我像这样向 UIImageView 添加了子层

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)

然后我重写了 touchesbegan 函数,以便在点击形状时显示和隐藏。

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
                }
            }
        }
    }
}