使用 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
}
}
}
}
}
我正在尝试为 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
}
}
}
}
}