UIGestureRecognizer 子类——touchesMoved 自动改变状态为.changed

UIGestureRecognizer subclass-- touchesMoved automatically changes state to .changed

我正在尝试创建一个 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"
        }
    }
}

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

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 状态。

另请注意,您的预期可能不正确 ("I need to be able to decide for myself when we are in the .changed state")。正常且正确的行为是,在 touchesBegan 中声明状态为 .began 后,您的 touchesMoved 将以状态 .began 调用一次,手势识别器将立即前进到 .changed 自动。即正确;如果这是连续手势,那么当我们处于 .began 状态而不进入 .changed 状态时,就不可能发生 moved 事件。同样,这是一个测试:

import UIKit
import UIKit.UIGestureRecognizerSubclass

class MyRecognizer: UIGestureRecognizer {
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {
        super.touchesBegan(touches, with: event)
        if touches.count != 1 {
            state = .failed
            return
        }
        print(self.state.rawValue)
        self.state = .began
    }
    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent) {
        super.touchesMoved(touches, with: event)
        print("moved", 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)
    }

}