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 视图控制器的替代品。但如果你在它外面点击,整个事情就会被忽略(那是你目标的另一部分)。