ios - 查找触摸在路径上的位置(按百分比)

标签 ios swift cgpath

我有一个CGPath,在该路径上我检测到触摸。该路径基本上是一条直线或曲线,但没有填充。这个想法是用户抚摸路径,因此无论用户沿着路径抚摸什么地方,我都想用不同的笔划/颜色等绘制路径。

首先,为了确定触摸是否在路径内部,并给用户一些犯错的空间,我使用了 CGPathCreateCopyByStrokingPath 和 CGPointInsidePath 。这很好用。

接下来,我需要找出用户沿着路径抚摸了多远。这就是今天的问题。

完成后,我得到了 33% 之类的答案,那么我将简单地分配给路径上的 linesEnd 。 (两份副本,一份完整路径,一份在顶部,StrokeEnd 设置为用户迄今为止用手指抚摸的完整路径的百分比)。

有什么想法可以找到用户手指抚摸路径的距离吗?

最佳答案

我已经在这方面工作了很长时间,并且想分享我的答案(顺便说一句,我就是问这个问题的人)。

  1. 我想检测沿路径的触摸(例如贝塞尔曲线)。问题是它只能告诉您触摸是否击中路径,但不会告诉您触摸的位置(使用 CGPathContainsPoint)。
  2. 为避免用户恰好在路径上点击,使用 CGPathCreateCopyByStrokingPath 创建一个更胖的版本),以便检查触摸。
  3. 主要问题仍然是,触摸命中了路径上的何处。我所做的是使用 CGPathCreateCopyByDashingPath 以最小间距创建一个虚线路径副本。该路径从未实际显示。然后我使用 CGPathApply 将每个路径元素保存在一个数组中。
  4. 当检测到触摸并且位于“宽路径”内时,我只是循环遍历路径破折号元素数组,检查到每个路径破折号起点的距离(只是常规毕达哥拉斯) -元素。

如果触摸点最接近第 14 个元素,并且有例如总共 140 个元素,这意味着我们已经完成了 10%。

  1. 现在我们有了百分比。我现在想要的是画出触摸的路径。我尝试在路径上使用建议的 strokeEnd 属性。这与我计算的百分比完全不符。实际上,在我看来,这是非常不准确的。或者我的计算是。

无论如何,既然我们已经有了所有的路径元素,并且知道要停在哪一个(第 14 个元素),我所做的就是使用路径元素构建一条新路径。因为我不想要一条虚线路径(这只是找出触摸在长的连续路径上的位置的技巧),所以我只是跳过了所有 moveTo 路径元素(第一个元素除外)。这将创建一条连续的路径。

CGPathApply - 按要求

// MARK: - Stuff for CGPathApply

typealias MyPathApplier = @convention(block) (UnsafePointer<CGPathElement>) -> Void
// http://stackoverflow.com/questions/24274913/equivalent-of-or-alternative-to-cgpathapply-in-swift
// Note: You must declare MyPathApplier as @convention(block), because
// if you don't, you get "fatal error: can't unsafeBitCast between
// types of different sizes" at runtime, on Mac OS X at least.

func myPathApply(path: CGPath!, block: MyPathApplier) {
    let callback: @convention(c) (UnsafeMutablePointer<Void>, UnsafePointer<CGPathElement>) -> Void = { (info, element) in
        let block = unsafeBitCast(info, MyPathApplier.self)
        block(element)
    }

    CGPathApply(path, unsafeBitCast(block, UnsafeMutablePointer<Void>.self), unsafeBitCast(callback, CGPathApplierFunction.self))
}

关于ios - 查找触摸在路径上的位置(按百分比),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34156815/

相关文章:

arrays - 如何在 Swift 中按属性值对自定义对象数组进行排序

ios - 'CGAffineTransform' 不可转换为 'ConstUnsafePointer<CGAffineTransform>'

iphone - 将CGPath转换为UIImage

ios - 从模态视图刷新背景 View

ios - 指定初始化程序的目的

ios - 在搜索栏的左侧和右侧添加按钮

ios - 自定义初始化方法

ios - Espresso ANERuntimeEngine 程序推理溢出

ios - 在子节点的显示隐藏上快速重新调整/调整布局(ASDisplayNode)

core-graphics - 在 CGPath 上获取随机 CGPoint