gpt4 book ai didi

ios - Swift 3 中的 CAShapeLayer 点击检测

转载 作者:可可西里 更新时间:2023-11-01 02:00:37 25 4
gpt4 key购买 nike

我有一个 CAShapeLayer,我已将其填充颜色标记为透明。

当我点击线上时,它并不总是检测 CAShapeLayer cgpath 是否包含点击点。我的代码如下:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first
guard let point = touch?.location(in: self) else { return }

for sublayer in self.layer.sublayers! {
if let l = sublayer as? CAShapeLayer {
if let path = l.path, path.contains(point) {
print("Tap detected")
}
}
}
}

在某些情况下,如果我真的点击在线的中心,它会检测到它。 enter image description here

于是想把6到45的线弄得很粗,还是不行。然后我想在这之后将填充设为灰色,现在当我点击填充灰色时它总是检测到点击。我真的很困惑,为什么它检测到点击填充或线的正中心为什么不检测线的整个厚度。

enter image description here

最佳答案

Swift 4,答案基于解释和链接 CGPath Hit Testing - Ole Begemann (2012) 作者 caseynolan 在其他评论中:

来自 Ole Begemann 博客:

contains(point: CGPoint)

This function is helpful if you want to hit test on the entire region the path covers. As such, contains(point: CGPoint) doesn’t work with unclosed paths because those don’t have an interior that would be filled.

copy(strokingWithWidth lineWidth: CGFloat, lineCap: CGLineCap, lineJoin: CGLineJoin, miterLimit: CGFloat, transform: CGAffineTransform = default) -> CGPath

This function creates a mirroring tapTarget object that only covers the stroked area of the path. When the user taps on the screen, we iterate over the tap targets rather than the actual shapes.


我的代码解决方案

我使用链接到函数 tap() 的 UITapGestureRecognizer:

var tappedLayers = [CAShapeLayer]()

@IBAction func tap(_ sender: UITapGestureRecognizer) {
let point = sender.location(in: imageView)

guard let sublayers = imageView.layer.sublayers as? [CAShapeLayer] else {
return
}

for layer in sublayers {
// create tapTarget for path
if let target = tapTarget(for: layer) {
if target.contains(point) {
tappedLayers.append(layer)
}
}
}
}

fileprivate func tapTarget(for layer: CAShapeLayer) -> UIBezierPath? {
guard let path = layer.path else {
return nil
}

let targetPath = path.copy(strokingWithWidth: layer.lineWidth, lineCap: CGLineCap.round, lineJoin: CGLineJoin.round, miterLimit: layer.miterLimit)

return UIBezierPath.init(cgPath: targetPath)
}

关于ios - Swift 3 中的 CAShapeLayer 点击检测,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46653321/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com