@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
}
}
}
}
}
没有内置机制来检测不规则形状的点击。标准的UIView点击检测使用框架矩形。(同样适用于CALayers,如sketchyTech在上面的评论中建议的那样。)
我建议将身体区域绘制为贝塞尔路径。您可以创建一个自定义的UIView子类(BodyView),它将管理包含贝塞尔路径的每个BodyRegion对象的数组。
UIBezierPath类包括一个containsPoint方法,让您知道一个点是否在路径内。您的BodyView可以使用它来决定哪个路径对象被点击。
贝塞尔路径将处理绘制身体区域和确定哪个部分被点击。
containsPoint()
方法,并在无法正确运行时发布问题。 - Duncan C
CALayer
的hitTest
只适用于图层的矩形边界。OP 的插图显示了不规则的形状。我认为在这种情况下使用贝塞尔路径和containsPoint
更好。(此外,图层是一个低级系统组件,引入了另一层复杂性。)它们确实很强大,但我认为在这种情况下它们不值得增加额外的复杂性。 - Duncan C