SWIFT:检测当前视图外的触摸
SWIFT: detect touch outside current view
这是一个比较简单的问题。我有一个 tableViewController,它会在用户按下按钮后出现,但它不会覆盖整个屏幕,从而使之前的一些视图控制器可见。当 touchLocation.x 属性(触摸的 CGPoint 位置的 x 坐标)超过某个点时,我试图使用 touchesEnded 关闭 tableViewController。问题是,当触摸超过 x 点(在 tableViewController 之外)时,touchesEnded 实际上没有收到任何东西或被调用,因为它在视图之外,所以我的 dismiss 函数没有被调用。有谁知道如何检测当前视图之外的触摸,以便当前视图之外的任何触摸都会消除所述当前视图?谢谢
您需要在 table 视图后面有一个覆盖屏幕的清晰视图,可以检测到 table 视图外的点击。
似乎很难掌握如何做到这一点的一般概念,所以这里简单演示一下基本原理。这是一个完整的项目;只需将其全部复制并粘贴到新的香草项目的视图控制器中即可:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = .yellow
let b = UIButton(type: .system)
b.setTitle("Present", for: .normal)
b.sizeToFit()
b.addTarget(self, action: #selector(tap), for: .touchUpInside)
b.frame.origin = CGPoint(x: 100, y: 100)
self.view.addSubview(b)
}
@objc func tap() {
self.present(VC2(), animated: true)
}
}
class VC2: UIViewController {
init() {
super.init(nibName: nil, bundle: nil)
self.modalPresentationStyle = .overFullScreen
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
self.view.backgroundColor = .clear
let tgr = UITapGestureRecognizer(target: self, action: #selector(tap))
self.view.addGestureRecognizer(tgr)
let child = VC3()
self.addChild(child)
self.view.addSubview(child.view)
child.didMove(toParent: self)
child.view.frame.size.width = 0.7*self.view.bounds.width
child.view.frame.size.height = 0.7*self.view.bounds.height
child.view.center = CGPoint(x:self.view.bounds.midX, y:self.view.bounds.midY)
child.view.autoresizingMask = [.flexibleTopMargin, .flexibleBottomMargin, .flexibleLeftMargin, .flexibleRightMargin]
}
@objc func tap() {
print("farewell")
self.dismiss(animated: true)
}
}
class VC3: UIViewController {
init() {
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
self.view.backgroundColor = .green
let tgr = UITapGestureRecognizer(target: self, action: #selector(tap))
self.view.addGestureRecognizer(tgr)
}
@objc func tap() {
print("ouch, stop that")
}
}
运行 项目,您将看到带有“演示”按钮的黄色视图;点击演示按钮。一个绿色的视图漂浮在屏幕中间;请注意黄色视图在它后面仍然可见(这是您目标的一部分)。假设那是 table 视图。如果您点击它,该点击会被 VC3 检测到,它是我们 table 视图控制器的替代品。但如果你在它外面点击,整个事情就会被忽略(那是你目标的另一部分)。
这是一个比较简单的问题。我有一个 tableViewController,它会在用户按下按钮后出现,但它不会覆盖整个屏幕,从而使之前的一些视图控制器可见。当 touchLocation.x 属性(触摸的 CGPoint 位置的 x 坐标)超过某个点时,我试图使用 touchesEnded 关闭 tableViewController。问题是,当触摸超过 x 点(在 tableViewController 之外)时,touchesEnded 实际上没有收到任何东西或被调用,因为它在视图之外,所以我的 dismiss 函数没有被调用。有谁知道如何检测当前视图之外的触摸,以便当前视图之外的任何触摸都会消除所述当前视图?谢谢
您需要在 table 视图后面有一个覆盖屏幕的清晰视图,可以检测到 table 视图外的点击。
似乎很难掌握如何做到这一点的一般概念,所以这里简单演示一下基本原理。这是一个完整的项目;只需将其全部复制并粘贴到新的香草项目的视图控制器中即可:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = .yellow
let b = UIButton(type: .system)
b.setTitle("Present", for: .normal)
b.sizeToFit()
b.addTarget(self, action: #selector(tap), for: .touchUpInside)
b.frame.origin = CGPoint(x: 100, y: 100)
self.view.addSubview(b)
}
@objc func tap() {
self.present(VC2(), animated: true)
}
}
class VC2: UIViewController {
init() {
super.init(nibName: nil, bundle: nil)
self.modalPresentationStyle = .overFullScreen
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
self.view.backgroundColor = .clear
let tgr = UITapGestureRecognizer(target: self, action: #selector(tap))
self.view.addGestureRecognizer(tgr)
let child = VC3()
self.addChild(child)
self.view.addSubview(child.view)
child.didMove(toParent: self)
child.view.frame.size.width = 0.7*self.view.bounds.width
child.view.frame.size.height = 0.7*self.view.bounds.height
child.view.center = CGPoint(x:self.view.bounds.midX, y:self.view.bounds.midY)
child.view.autoresizingMask = [.flexibleTopMargin, .flexibleBottomMargin, .flexibleLeftMargin, .flexibleRightMargin]
}
@objc func tap() {
print("farewell")
self.dismiss(animated: true)
}
}
class VC3: UIViewController {
init() {
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
self.view.backgroundColor = .green
let tgr = UITapGestureRecognizer(target: self, action: #selector(tap))
self.view.addGestureRecognizer(tgr)
}
@objc func tap() {
print("ouch, stop that")
}
}
运行 项目,您将看到带有“演示”按钮的黄色视图;点击演示按钮。一个绿色的视图漂浮在屏幕中间;请注意黄色视图在它后面仍然可见(这是您目标的一部分)。假设那是 table 视图。如果您点击它,该点击会被 VC3 检测到,它是我们 table 视图控制器的替代品。但如果你在它外面点击,整个事情就会被忽略(那是你目标的另一部分)。