2017-08-02 100 views
0

我想創建一個UIGestureRecognizer子類,並在touchesMoved我沒有代碼,但state被設置爲.changedUIGestureRecognizer subclass-- touchesMoved自動更改狀態.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

您的測試方法有缺陷。我想這(這是我的測試應用程序的完整代碼):

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將被調用一次,狀態爲.began,手勢識別器將自動立即前進到.changed。那就是正確;如果這是連續的手勢,那麼在moved事件應該進入而我們處於.began狀態時不會出現這種情況,而我們不會進入.changed。再次,這裏是一個測試:

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) 
    } 

} 
+0

謝謝。不幸的是,我嘗試了沒有運氣。我從上面的例子中刪除了它,以顯示我甚至沒有觸及超類。我會重新加入,以便更清楚。 – MH175

+0

看到我修改的答案。 – matt

+0

謝謝。我現在看到 - 非常有幫助。除非觸摸移動了一定的最小數量,否則我試圖做的不是移動到.changed。 – MH175