iOS:无法检测到CALayer界限之外的触摸

时间:2017-07-30 18:20:34

标签: ios swift cocoa-touch frame calayer

我创建了一个可重用的多状态交换机,它扩展自UIControl,看起来类似于默认的UISwitch,具有两个以上的状态。实现类似于为每个状态添加CALayers,以及在UIView上突出显示所选状态的一个附加层。

UI看起来像这样

multi state switch

问题是当用户在方形边框外部轻敲时,我无法识别触摸状态,如图中所示。有一个简单的方便方法(getIndexForLocation)我已经添加了返回选定状态的索引,给定了触摸点。使用返回的选定索引,我将突出显示指示符的位置移动到所选状态的中心位置。

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
}

使用最后一个触摸点从UIControl的endTracking(touch:for event)方法调用上述方法。

如何更改此方法,以便我可以获得触摸/选择状态的索引,即使用户触摸了图像。触摸区域可以近似位于状态图像中心顶部的高亮圆圈区域。

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

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

您正在测试if sLayers![i].frame.contains(point)。因此,最简单的解决方案是制作每个&#34;按钮的框架。更大 - 足够大,可以包含您想要触摸的整个区域,因为这个&#34;按钮&#34;。请记住,即使框架很大,绘图也可能很小。

另外,除了你的代码是愚蠢的,因为你基本上执行命中测试。对图层的命中测试是内置的,所以一旦你的框架正确,你所要做的就是在超级图层上调用hitTest(_:)。这将告诉你哪个图层被点击。

(当然,使用子视图而不是图层甚至可以更好。视图可以检测触摸;图层可以&#39; t。)