UIGestureRecognizer子类 - touchesMoved自动将状态更改为.changed

时间:2017-08-02 17:08:25

标签: ios swift uigesturerecognizer

我正在尝试创建UIGestureRecognizer子类,并且在touchesMoved我没有代码,但state被设置为.changed

有谁知道为什么会这样?当我们处于.changed状态时,我需要自己做出决定。

如果我删除了touchesBegan功能并且从未转移到.began,则不会发生这种情况。

import UIKit.UIGestureRecognizerSubclass

class MyRecognizer: UIGestureRecognizer {

    private var refView: UIView? {
        return self.view?.window
    }


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

       if touches.count != 1 {
            state = .failed
            return
        }

        guard let location = touches.first?.location(in: refView) else {
            self.state = .failed
            return
        }

       state = .began

    }

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent) {
        // there is no code here!
    }

   //This is how I'm debugging state
   override var state: UIGestureRecognizerState {
      get { return super.state }
      set {
          super.state = newValue
          print("state = \(newValue.debugDescription)")
      }  
    }

}

extension UIGestureRecognizerState: CustomDebugStringConvertible {
    public var debugDescription: String {
        switch self {
        case .began: return "began"
        case .possible: return "possible"
        case .changed: return "changed"
        case .ended: return "ended"
        case .cancelled: return "cancelled"
        case .failed: return "failed"
        }
    }
}

1 个答案:

答案 0 :(得分:1)

您的测试方法存在缺陷。我试过这个(这是我的测试应用程序的完整代码):

import UIKit
import UIKit.UIGestureRecognizerSubclass

class MyRecognizer: UIGestureRecognizer {
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {
        super.touchesBegan(touches, with: event)
        print(self.state.rawValue)
    }
    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent) {
        super.touchesMoved(touches, with: event)
        print(self.state.rawValue)
    }
}

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        let g = MyRecognizer(target: self, action: #selector(grFired))
        self.view.addGestureRecognizer(g)
        // Do any additional setup after loading the view, typically from a nib.
    }

    @objc func grFired(_ g:UIGestureRecognizer) {
        print("here", g.state.rawValue)
    }

}

然后我拖动手势识别器附加到的背景视图。我的手势识别器从未移动过possible状态。

另请注意,您的期望可能不正确(“我需要能够在我们处于.changed状态时自行决定”)。正常和正确的行为是,在.began中声明状态为touchesBegan后,状态为touchesMoved的{​​{1}}将被调用一次,手势识别器将立即提前自动到.began。那是正确的;如果这是连续的手势,那么当我们处于.changed状态时,如果没有我们继续moved.began事件就不会出现。再次,这是一个测试:

.changed