Pass touches through a UIViewController

2019-04-26 14:13发布

I have a view controller that I overlay on top of another view controller. I just need the top view controller so I can overlay a temporary pop up notification, and having an overlayed VC allows me to present this over a UITableViewController as you can't add subviews to tableview controllers directly.

Is it possible to interact with the bottom view controller while it has another view controller covering it. If this were a view or a window you would achieve this by setting user interaction to false or using hitTest but neither of these approaches works for a view controller.

3条回答
Ridiculous、
2楼-- · 2019-04-26 14:40

As you've correctly deduced, when you present one view controller over another, the presenting view controller's view is not in the responder chain. Touches in the presented view controller's view therefore cannot "fall through" to it. You will have to route your message from the presented view controller's view in some other way.

查看更多
仙女界的扛把子
3楼-- · 2019-04-26 15:03

You don't have access to previous ViewController, and user can't interact by touch with it. Property modalPresentationStyle = .OverCurrentContext just means that views under presented content are not removed from the view hierarchy.

查看更多
劫难
4楼-- · 2019-04-26 15:06

Create subclass like this

class TouchDelegatingView: UIView {
    weak var touchDelegate: UIView? = nil


    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
        guard let view = super.hitTest(point, with: event) else {
            return nil
        }

        guard view === self, let point = touchDelegate?.convert(point, from: self) else {
            return view
        }

        return touchDelegate?.hitTest(point, with: event)
    }
}

Then in your ViewController set view class (you can do it directly in xib, or inside loadView() method)

And add

class ViewController: UIViewController {
    override func viewDidLoad() {
        viewDidLoad()

        if let delegatingView = view as? TouchDelegatingView {
            delegatingView.touchDelegate = presentingViewController?.view
        }
    }
}

Also you can use this mechanism to delegate touches to any other view, no matter if it

查看更多
登录 后发表回答