Posts

Post not yet marked as solved
0 Replies
701 Views
I need to overlay an UIView on top of SwiftUI content. Instead of using UIViewController.present(_:animated:completion:), I simply add it to UIWindow hierarchy and apply constraints (I need it for additional customization, not important here). But I ran into a problem. Overlayed UIView passes tap gestures through itself, and underlying SwiftUI View gets clicked. You can see, that successive clicks make screen redder and redder—they basically insert more subviews. Weird thing is, that drag gestures, such as scrolling, don't go through. Video here: http://i.stack.imgur.com/gRk8a.gif What are the implications here? Why is tap going through, and not drag? struct ContentView: View { var body: some View { ScrollView(content: { Button("Click", action: overlayView) }) } private func overlayView() { let overlay: UIView = .init() overlay.translatesAutoresizingMaskIntoConstraints = false overlay.isUserInteractionEnabled = true overlay.backgroundColor = .red.withAlphaComponent(0.1) let windowView: UIView = UIApplication.shared.activeWindow!.rootViewController!.view windowView.addSubview(overlay) NSLayoutConstraint.activate([ overlay.leadingAnchor.constraint(equalTo: windowView.leadingAnchor), overlay.trailingAnchor.constraint(equalTo: windowView.trailingAnchor), overlay.topAnchor.constraint(equalTo: windowView.topAnchor), overlay.bottomAnchor.constraint(equalTo: windowView.bottomAnchor) ]) } } extension UIApplication { var activeWindow: UIWindow? { connectedScenes .filter { $0.activationState == .foregroundActive } .first { $0 is UIWindowScene } .flatMap { $0 as? UIWindowScene }? .windows .first { $0.isKeyWindow } } } The same problem doesn't occur when launching from pure UIKit: final class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .systemBackground let button: UIButton = .init() button.translatesAutoresizingMaskIntoConstraints = false button.addTarget(self, action: #selector(overlayView), for: .touchUpInside) button.setTitle("Click", for: .normal) button.setTitleColor(.systemBlue, for: .normal) view.addSubview(button) NSLayoutConstraint.activate([ button.centerXAnchor.constraint(equalTo: view.centerXAnchor), button.centerYAnchor.constraint(equalTo: view.centerYAnchor) ]) } @objc private func overlayView() { let overlay: UIView = .init() overlay.translatesAutoresizingMaskIntoConstraints = false overlay.isUserInteractionEnabled = true overlay.backgroundColor = .red.withAlphaComponent(0.1) let windowView: UIView = UIApplication.shared.activeWindow!.rootViewController!.view windowView.addSubview(overlay) NSLayoutConstraint.activate([ overlay.leadingAnchor.constraint(equalTo: windowView.leadingAnchor), overlay.trailingAnchor.constraint(equalTo: windowView.trailingAnchor), overlay.topAnchor.constraint(equalTo: windowView.topAnchor), overlay.bottomAnchor.constraint(equalTo: windowView.bottomAnchor) ]) } } I would appreciate if you could help with actually cutting off the tap gestures.
Posted Last updated
.