找到触摸路径的位置(按百分比)

时间:2015-12-08 13:12:40

标签: ios swift cgpath

我有CGPath,在那条路上我检测到了触摸。路径基本上是一条线或一条曲线,但它没有被填充。这个想法是用户描边路径,所以无论用户沿着路径描边,我都想用不同的笔触/颜色等绘制路径。

首先,要查找触摸是否在路径内,并为用户提供一些错误空间,我使用的是CGPathCreateCopyByStrokingPathCGPointInsidePath。这很好。

接下来,我需要找到用户描边路径的距离。这是今天的问题。

当完成后,我得到了33%的回答,那么我将在路径上对strokeEnd进行简单的分配。 (两个副本,一个完整路径,一个在顶部,strokeEnd设置为用户到目前为止用手指抚摸的完整路径的百分比。)

如何找到用户抚摸手指的路径有多远?

2 个答案:

答案 0 :(得分:1)

我已经做了很长一段时间了,并想分享我的答案(我是那个问btw问题的人)。

  1. 我想检测路径上的触摸(例如Bezier曲线)。问题是它只能告诉你触摸是否触及路径,而不是在哪里(使用CGPathContainsPoint)。
  2. 为避免用户在路径上完全点击,请使用CGPathCreateCopyByStrokingPath)创建更加丰富的版本,以便检查是否触摸。
  3. 主要问题仍然是,其中沿着路径触碰了。我所做的是用CGPathCreateCopyByDashingPath创建一个虚线路径副本,间距最小。此路径从未实际显示。然后我用CGPathApply保存数组中的每个路径元素来获得它的每一部分。
  4. 当检测到触摸并且在"胖路径"内时,我只是循环遍历路径破折号元素的数组,检查距离(只是常规的毕达哥拉斯)到起点每个path-dash-element。
  5. 如果触摸点最接近第14个元素,则例如总计140个元素,这意味着我们一路上都是10%。

    1. 现在我们有了百分比。我现在想要的是绘制路径直到触摸。我尝试在路径上使用建议的strokeEnd属性。这根本不符合我计算的百分比。实际上,在我看来,这是非常不准确的。或者也许我的计算是。
    2. 无论如何,既然我们已经拥有了所有的路径元素,并知道要停在哪一个(第14个元素),我所做的就是使用path-elements构建一个新的路径。由于我不想要一个虚线路径(这只是找到触摸在长连续路径上的位置的技巧),我只是跳过了所有的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))
      }
      

答案 1 :(得分:0)

我有一个实用工具类GHPathUtilies.m,其中包含一个方法:

+(CGFloat) totalLengthOfCGPath:(CGPathRef)pathRef

这都是用Objective-C编写的,但可能你可以使用相同的技术沿路径元素走,使用CGPathApply,直到你足够近,或者已经通过了目标点。一般的想法是将每个元素之间的曲线分成小的线段,并保持每个段的长度的运行总和。

当然,如果路径自身翻倍,你必须弄清楚哪个点是触点。