日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

iOS 手势冲突

發布時間:2023/12/20 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 iOS 手势冲突 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

手勢沖突處理

  • 1、自定義手勢優先級
  • 2、阻止手勢向響應鏈傳遞執行
  • 3、實現協議方法 `UIGestureRecognizerDelegate` 控制手勢沖突
  • 4、自定義手勢

手勢沖突主要的三種解決思路:

  • 設置手勢優先級 requireGestureRecognizerToFail:
  • 阻止手勢向事件傳遞鏈執行 cancelsTouchesInView、delaysTouchesBegan
  • 實現協議方法 UIGestureRecognizerDelegate
  • (自定義手勢)重寫父類中的個別方法 @interface UIGestureRecognizer (UIGestureRecognizerProtected)

1、自定義手勢優先級

場景一:
自定義多手勢沖突。例如我們設置的單次點擊、雙擊和三次點擊手勢,需要設置優先識別三擊手勢,識別失敗后再識別雙擊手勢;同理,雙擊手勢識別失敗后再識別單擊手勢。

/// 自定義多手勢沖突func test_1() {let oneGes = UITapGestureRecognizer(target: self, action: #selector(oneTap(tapGes:)))oneGes.numberOfTapsRequired = 1self.scrollVeiw.addGestureRecognizer(oneGes)let twoGes = UITapGestureRecognizer(target: self, action: #selector(twoTap(tapGes:)))twoGes.numberOfTapsRequired = 2self.scrollVeiw.addGestureRecognizer(twoGes)let threeGes = UITapGestureRecognizer(target: self, action: #selector(threeTap(tapGes:)))threeGes.numberOfTapsRequired = 3self.scrollVeiw.addGestureRecognizer(threeGes)// 優先級設置oneGes.require(toFail: twoGes)twoGes.require(toFail: threeGes)}@objc func oneTap(tapGes: UITapGestureRecognizer) {print("=================> oneTap")}@objc func twoTap(tapGes: UITapGestureRecognizer) {print("=================> twoTap")}@objc func threeTap(tapGes: UITapGestureRecognizer) {print("=================> threeTap")}

2、阻止手勢向響應鏈傳遞執行

當自定義手勢和系統手勢沖突,可以使用手勢的兩個屬性:cancelsTouchesInView、delaysTouchesBegan進行處理。
例如:頁面添加自定義手勢 UIPanGestureRecognizer,與頁面上的系統手勢 touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) 回調方法沖突,可利用該屬性屏蔽掉系統手勢。

  • cancelsTouchesInView(是否取消向事件響應鏈傳遞):
    默認 YES,自定義的手勢響應后,系統手勢不再響應,但自定義手勢識別前,會先執行系統手勢。
    設置為 NO 后,自定義手勢和系統手勢會同時識別響應。
  • delaysTouchesBegan(延遲響應鏈的識別):
    默認 NO,先執行響應鏈中的方法(系統方法),識別到自定義手勢后,不再執行系統方法。
    設置為 YES 后,優先識別自定義手勢,當自定義手勢識別失敗后才會響應系統方法

屏蔽掉系統方法,我們只需要將屬性 delaysTouchesBegan 設置為 YES 即可:

// MARK: - 阻止手勢向事件傳遞鏈傳遞func test_2() {let panGes = UIPanGestureRecognizer(target: self, action: #selector(panGestureAction(panGes:)))// 阻止手勢向事件傳遞鏈執行 默認是 YES// panGes.cancelsTouchesInView = false// 延遲手勢向事件傳遞鏈執行 默認是 NOpanGes.delaysTouchesBegan = trueself.view.addGestureRecognizer(panGes)}@objc func panGestureAction(panGes: UIPanGestureRecognizer) {let point = panGes.location(in: self.view)print("********************")print("W ==> \(point.x)")print("H ==> \(point.y)")}override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {let point = touches.first?.location(in: self.view)print("=====================")print("W ==> \(String(describing: point?.x))")print("H ==> \(String(describing: point?.y))")}

3、實現協議方法 UIGestureRecognizerDelegate 控制手勢沖突

常用的是第二個協議方法 gestureRecognizer: shouldRecognizeSimultaneouslyWithGestureRecognizer:

//手指觸摸屏幕后回調的方法,返回NO則不再進行手勢識別,方法觸發等 - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch; //開始進行手勢識別時調用的方法,返回NO則結束,不再觸發手勢 - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer; //是否支持多時候觸發,返回YES,則可以多個手勢一起觸發方法,返回NO則為互斥 - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer; //下面這個兩個方法也是用來控制手勢的互斥執行的 //這個方法返回YES,第一個手勢和第二個互斥時,第一個會失效 - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRequireFailureOfGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer NS_AVAILABLE_IOS(7_0); //這個方法返回YES,第一個和第二個互斥時,第二個會失效 - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer NS_AVAILABLE_IOS(7_0);

4、自定義手勢

系統提供給我們的手勢可以滿足絕大多數的業務場景需求,對于特殊情況,可能需要用到自定義的手勢。
繼承 UIGestureRecognizer ,并重寫以下方法:

override func reset() {super.reset()state = .possible}override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {super.touchesBegan(touches, with: event)state = .began}override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent) {super.touchesBegan(touches, with: event)}override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent) {super.touchesEnded(touches, with: event)state = .ended}override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent) {super.touchesCancelled(touches, with: event)state = .changed}

根據其它博客內容提示,如需修改手勢的 state 屬性,需要引入 import UIKit.UIGestureRecognizerSubclass,但根據實測,未引入也不會報錯。

總結

以上是生活随笔為你收集整理的iOS 手势冲突的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。