【发布时间】:2021-07-28 19:00:21
【问题描述】:
我尝试实现一个全局手势识别器,它能够全局检测点击事件。
以下是我的第一次尝试。
第一次尝试:全局点击手势识别器。 (不完美)
import UIKit
extension UIWindow {
static var key: UIWindow! {
if #available(iOS 13, *) {
return UIApplication.shared.windows.first { $0.isKeyWindow }
} else {
return UIApplication.shared.keyWindow
}
}
}
class ViewController: UIViewController {
// Lazy is required as self is not ready yet without lazy.
private lazy var globalGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(globalTapped))
private func installGlobalGestureRecognizer() {
UIWindow.key.removeGestureRecognizer(globalGestureRecognizer)
UIWindow.key.addGestureRecognizer(globalGestureRecognizer)
}
@objc func globalTapped() {
print("global tapped!")
}
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func handleTapForRedView(_ gesture: UITapGestureRecognizer) {
print("red view tap")
}
@IBAction func yellowButtonTap(_ sender: Any) {
print("yellow button tap")
}
@IBAction func installGlobalGestureButtonTap(_ sender: Any) {
print("install global gesture")
installGlobalGestureRecognizer()
}
}
但是,这样的解决方案并不完美。当点击区域落在按钮等其他可触摸组件上时,globalGestureRecognizer 无法捕获事件。请参考以下视频。
正如您在视频中看到的,当修饰区域为黄色按钮或红色自定义视图时,“全局点击!”不会被打印出来。
我再试一次。
第二次尝试:只能检测到轻击(不完美)
import UIKit
extension UIWindow {
static var key: UIWindow! {
if #available(iOS 13, *) {
return UIApplication.shared.windows.first { $0.isKeyWindow }
} else {
return UIApplication.shared.keyWindow
}
}
}
extension ViewController: UIGestureRecognizerDelegate {
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
print("global tapped down!")
return false
}
}
class ViewController: UIViewController {
// Lazy is required as self is not ready yet without lazy.
private lazy var globalGestureRecognizer = UITapGestureRecognizer(target: self, action: nil)
private func installGlobalGestureRecognizer() {
UIWindow.key.removeGestureRecognizer(globalGestureRecognizer)
UIWindow.key.addGestureRecognizer(globalGestureRecognizer)
globalGestureRecognizer.delegate = self
}
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func handleTapForRedView(_ gesture: UITapGestureRecognizer) {
print("red view tap")
}
@IBAction func yellowButtonTap(_ sender: Any) {
print("yellow button tap")
}
@IBAction func installGlobalGestureButtonTap(_ sender: Any) {
print("install global gesture")
installGlobalGestureRecognizer()
}
}
正如您在视频中看到的,当点击区域落在按钮等其他可触摸组件上时,globalGestureRecognizer 能够捕获事件。
但是,这仅限于点击事件。我希望能够捕捉到点击事件。
有人知道怎么做吗?我的期望是
- 全局手势不会阻止按钮、自定义视图的原始事件...
- 全局手势将能够在任何地方检测到触摸事件。即使事件落在按钮、自定义视图...全局手势仍然能够检测到它们。
【问题讨论】: