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