簡體   English   中英

如何取消LongPressGestureRecognizer?

[英]How to cancel LongPressGestureRecognizer?

我有一個分配了LongPressGestureRecognizer的視圖,該視圖調用以下方法:

@IBAction func longPressOnView1Recognized(_ sender: UIGestureRecognizer) {

    if sender.state == .began {
        // this runs when user's finger is down a "long time"
    }
    if sender.state == .ended {
        // this runs when user's finger goes up again after the .began state 
    }

}

所有這一切都按預期工作,但是我正在嘗試找到一種(好的/正確的)方式,可以在用戶的​​手指仍不放下時以編程方式cancel長按識別器(在某些情況下)。

也就是說, 用戶的手指仍在視圖上且識別器已進入.began狀態時(但用戶抬起手指之前-識別器進入.end狀態之前)...是否存在一些代碼我們可以運行該命令,以防止用戶抬起手指時觸發上述方法……就像過早地告訴IOS在該手勢的其余部分不再監聽UP事件一樣?

我已經閱讀了這些文檔 ,但是我對IOS touch沒有太多的經驗,而且我似乎找不到用於此目的的任何方法。

我的GestureRecognizer.reset()似乎不符合我的描述。

我可以想到兩種可能性:

1)一個布爾型標志,它將位於if sender.state == .ended {}閉包內

2):

myLongPressRecognizer.isEnabled = false
myLongPressRecognizer.isEnabled = true

這兩種方法都可以,但是看起來並不那么出色。

禁用和重新啟用手勢識別器都很不錯

myLongPressRecognizer.isEnabled = false
myLongPressRecognizer.isEnabled = true

是完全正確的。

我擔心的是您不完全了解手勢識別器。 處理手勢識別器時,應始終使用switch語句。 檢查評論:

func handleLongPressGestureRecognizer(_ sender: UIGestureRecognizer) {

    switch sender.state {
    case .began:
        // This will be called only once when the gesture starts
        print("Long press did begin at \(sender.location(in: sender.view))")
    case .changed:
        // This will be called whenever your finger moves (at some frequency obviously).
        // At this point your long press gesture is acting exactly the same as pan gesture
        print("Long press changed position to \(sender.location(in: sender.view))")
    case .ended:
        // This is when user lifts his finger assuming the gesture was not canceled
        print("Long press ended at \(sender.location(in: sender.view))")
    case .cancelled:
        // This is equally important as .ended case. You gesture may be canceled for many reasons like a system gesture overriding it. Make sure to implement logic here as well.
        print("Long press canceled at \(sender.location(in: sender.view))")
    case .failed, .possible:
        // These 2 have been added additionally at some point. Useless as far I am concerned.
        break
    }

}

因此,至少您應該處理已取消的狀態。 但也請注意,無論何時移動手勢,都會觸發更改后的狀態。

您已經有了解決方案。 切換UILongPressGestureRecognizer isEnabled是最好的方法。 無法設置state屬性,因為它是一個只能獲取的屬性。

open var state: UIGestureRecognizer.State { get } // the current state of the gesture recognizer

isEnabled屬性記錄為:

默認為是。 禁用的手勢識別器將不會收到觸摸。 當更改為NO時,如果手勢識別器當前正在識別手勢,它將被取消。

您可以導入手勢識別器標頭:

import UIKit.UIGestureRecognizer

這將使state屬性成為readwrite屬性。 因此,要取消手勢,只需將其state更改為.cancelled

因此,例如,您可以在識別出長按手勢識別器一秒鍾后取消它,例如:

weak var timer: Timer?

@objc func handleLongPress(_ gesture: UILongPressGestureRecognizer) {
    switch gesture.state {
    case .began:
        print("began")
        timer?.invalidate()
        timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: false) { _ in
            gesture.state = .cancelled
        }

    case .ended, .cancelled:
        print(gesture.state == .ended ? "Ended" : "Cancelled")
        timer?.invalidate()

    default:
        break
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM