要求很簡單:當用戶觸摸螢屏并按住手指時,我想啟動一個活動(例如在螢屏上畫圓圈)。當手指再次抬起時,該活動將立即停止。所以我使用了UILongPressGestureRecognizer. 這會產生一個 .began 和 .ended 事件。但問題是當一個activity基于.began事件啟動時,只要activity正在進行,.ended事件就不會發生。我對 .ended 事件的意圖是它將停止啟動的活動。以這種方式,活動執行將被限制在手指觸摸和抬起之間的時間。
我將示例代碼增強到甚至 2 個獨立的代碼,UILongPressGestureRecognizers它們可以使用該UIGestureRecognizerDelegate構造同時作業。兩個識別器的同時功能起作用。然而,當其中一個啟動活動時,第二個識別器也不會接收事件,直到活動結束。
這個微不足道的要求如何實作?
這是我的示例代碼。該活動被簡化為 10 個列印陳述句。每秒 1 個。當觸摸手指在 2 秒后抬起時,回圈將繼續剩余 8 秒。
import UIKit
class ViewController: UIViewController {
var fingerDown = false
@IBOutlet var MyLongPress1: UILongPressGestureRecognizer!
@IBOutlet var MyLongPress2: UILongPressGestureRecognizer!
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func handleLongPress1(_ gesture: UILongPressGestureRecognizer) {
if (gesture as AnyObject).state == .began {
print("longPress1 began")
fingerDown = true
myActivity()
} else if (gesture as AnyObject).state == .ended {
print("longPress1 ended")
fingerDown = false
}
}
@IBAction func handleLongPress2(_ gesture: UILongPressGestureRecognizer) {
if (gesture as AnyObject).state == .began {
print("longPress2 began")
fingerDown = true
} else if (gesture as AnyObject).state == .ended {
print("longPress2 ended")
fingerDown = false
}
}
func myActivity() {
var count = 0
while fingerDown && count < 10 {
sleep(1)
count = 1
print("in myActivity \(count)")
}
}
}
extension ViewController: UIGestureRecognizerDelegate {
func gestureRecognizer(
_ gestureRecognizer: UIGestureRecognizer,
shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer
) -> Bool {
return true
}
}
任何好的建議將不勝感激!
uj5u.com熱心網友回復:
您正在函式中執行同步代碼。
相反,您應該做的是創建一個異步的、可取消的操作,該操作從事件開始.began,并在事件時取消它.ended。這方面的代碼太復雜了,無法撰寫并在這里給出答案。相反,您可以參考像這樣的并發/異步代碼教程來正確實作您正在嘗試做的事情。
一個更簡單但仍然有效的解決方案是簡單地異步呼叫您的函式,因此它不會阻塞主執行緒:
DispatchQueue.global().async {
self.myActivity()
}
在您的代碼中進行這樣的異步呼叫是可以的,但是代碼中還有其他問題使得它不是很干凈。例如,您的代碼依賴于附加fingerDown狀態而不是實際的手勢狀態;使用sleep等。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/412001.html
標籤:
