在自定义UIGestureRecognizer中跟踪位置

时间:2017-02-02 17:22:05

标签: ios swift

我正在建立自己的UIGestureRecognizer子类,以便组合点击和滑动手势并跟踪他们的滑动动作的方向。在这个预期的手势中,用户将触摸屏幕,让他们的手指完全离开屏幕一次或多次,然后将他们的手指返回到屏幕并拖动;这是一个轻击,然后立即轻扫。

我已经能够让这个识别器的实际手势部分正常工作,但我发现问题在于存储用户滑动所经过的点的踪迹。

首先,我将CGPoint s数组初始化为自定义识别器类的类成员

class UITapSwipeGestureRecognizer: UIGestureRecognizer {
    ...
    var trail: [CGPoint] = []

然后,在touchesBegan(_, with)中,我首先清除数组(如果不为空),并将起点提供给数组

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {
    ...
    if !trail.isEmpty {  //  EXC_BAD_ACCESS error thrown here
        trail.removeAll(keepingCapacity: true)
    }
    trail.append(location(in: view?.window))
    ...
}

我会继续在touchesMoved(_, with)讨论我的用法,但这足以触发我的问题。在第一次尝试访问数组时,在!trail.isEmpty,我收到以下错误:
    Thread 1 EXC_BAD_ACCESS (code=1, address=0x10)

我是否需要制作此阵列的线程安全版本?如果是这样,我该怎么做呢?或者我只是以错误的方式解决这个问题?

1 个答案:

答案 0 :(得分:0)

我已经能够通过StoryBoard添加手势识别器来复制您的错误。

当我以编程方式添加它时,我没有收到错误。

这是Gesture Recognizer类

import UIKit
import UIKit.UIGestureRecognizerSubclass

class MyGestureClass: UIGestureRecognizer
{
    var trail: [CGPoint] = []

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {
        super.touchesBegan(touches, with: event)
        state = .began

        if !trail.isEmpty {
            trail.removeAll(keepingCapacity: true)
        }
        trail.append(location(in: view?.window))
        print(trail.count) // Just for debugging
    }    

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent) {
        super.touchesMoved(touches, with: event)
        trail.append(location(in: view?.window))
        print(trail.count) // Just for debugging
    }

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent) {
        super.touchesEnded(touches , with: event)
        state = .ended
        print("Finished \(trail.count)") // Just for debugging
    }
}

以下是我从View Controller访问它的方法

override func viewDidLoad()
{
    super.viewDidLoad()

    let myRecognizer = MyGestureClass(target: self, action: #selector(self.tap(_:)))
    self.view.addGestureRecognizer(myRecognizer)
}

func tap(_ sender: UITapGestureRecognizer)
{
    // No need to do anything here, but appears to be required
}