的iOS:无法检测到的CALayer
问题描述:
我创建一个可重复使用的多态开关从UIControl看起来类似于默认UISwitch,有两个以上的状态延伸的边界之外的触摸。该实现就像添加CALayers为每个状态和一个额外的层来突出显示UIView上的选定状态。的iOS:无法检测到的CALayer
的UI看起来像这样
的问题是,当用户敲击就像图像中显示的平方境外我都认不出的状态的触摸。有一个简单的便利方法(getIndexForLocation),我添加了返回所选状态的索引,给定触点。使用返回的选定索引,我将高亮度指示符的位置移动到所选状态的中心位置。方法UIControl的与最后的触摸点:
func getIndexForLocation(_ point: CGPoint) -> Int {
var index = selectedIndex
let sLayers = self.controlLayer.sublayers
for i in 0..<totalStates {
if sLayers![i].frame.contains(point) {
index = i
}
}
return index
}
上述方法从endTracking(用于事件的触摸)调用。
我怎样才能改变这种方法,让我能得到触摸/选择状态的指标,即使用户已对图像周围的感动。触摸区域可以近似位于状态图像中心顶部的高亮圆圈区域。
self.controlLayer是其子层的所有国家和高亮指示灯容器层。
,增加了不如下
func performSwitch(to index: Int) ->() {
guard selectedIndex != index else {
return
}
let offsetDiff = CGFloat((index - selectedIndex) * (stateSize + 2))
let oldPosition = indicatorPosition
indicatorPosition.x += offsetDiff
let newPosition = indicatorPosition
let animation: CABasicAnimation = CABasicAnimation(keyPath: "position")
animation.timingFunction = CAMediaTimingFunction(controlPoints: 0.785, 0.135, 0.15, 0.86)
animation.duration = 0.6
animation.fromValue = NSValue(cgPoint: oldPosition!)
animation.toValue = NSValue(cgPoint: newPosition!)
animation.autoreverses = false
animation.delegate = self
animation.isRemovedOnCompletion = false
animation.fillMode = kCAFillModeForwards
self.selectedIndex = index
self.stateIndicator.add(animation, forKey: "position")
}
任何帮助提供与所选择的索引位置的动画的方法,将不胜感激。
答
你这么说if sLayers![i].frame.contains(point)
测试。因此,最简单的解决方案是让每个“按钮”的框架更大 - 足够大以包含您希望作为该“按钮”可触摸的整个区域。请记住,绘图可以很小,即使框架大。
而且,正如顺便说一句,你的代码是愚蠢的,因为你基本上是执行命中测试。对图层进行命中测试是内置的,因此,一旦您的图像正确无误,您只需在超级图层上调用hitTest(_:)
即可。这将告诉你哪个图层被点击。
(当然,它甚至会更好使用子视图代替层中的视图可以检测触摸;层不能。)