Skip to content

Fix: popup window blocks touches when tapOutsideToDismissPopup is false#206

Open
yaro-zakh wants to merge 1 commit intoMijick:mainfrom
yaro-zakh:fix/overlay-hit-testing
Open

Fix: popup window blocks touches when tapOutsideToDismissPopup is false#206
yaro-zakh wants to merge 1 commit intoMijick:mainfrom
yaro-zakh:fix/overlay-hit-testing

Conversation

@yaro-zakh
Copy link

Summary

  • When using PopupSceneDelegate, the popup UIWindow intercepts all touches even when overlayColor is .clear and tapOutsideToDismissPopup is false
  • The overlay always has .onTapGesture making it hit-testable, and SwiftUI container views (GeometryReader, ZStack) create full-screen UIKit backing views that hitTest finds

Fix

  • Added .allowsHitTesting(tapOutsideClosesPopup) to the overlay in PopupView.swift
  • Modified Window hitTest methods (iOS 17/18/26) to check for gesture recognizers when tapOutsideToDismissPopup is false — only touches on actual popup content are captured, container views pass through
  • Added hasGestureRecognizer helper to walk the view hierarchy

Test plan

  • Present a TopPopup with .overlayColor(.clear) and .tapOutsideToDismissPopup(false)
  • Verify tapping/scrolling behind the popup works (touches pass through)
  • Present a popup with .tapOutsideToDismissPopup(true) and verify tap-to-dismiss still works
  • Test on iOS 17, 18, and 26 paths

When using PopupSceneDelegate, the popup UIWindow intercepts all touches
even when the overlay is clear and tapOutsideToDismissPopup is disabled.
This happens because SwiftUI layout containers (GeometryReader, ZStack)
create full-screen UIKit backing views that are found by hitTest,
causing the window to claim touches meant for the main app window.

Changes:
- Window hitTest methods (iOS 17/18/26) now check for gesture recognizers
  when tapOutsideToDismissPopup is false. Only touches on views with
  gesture recognizers (actual popup content) are captured; touches on
  empty container views pass through to the underlying window.
- Overlay view has .allowsHitTesting(tapOutsideClosesPopup) so it does
  not create a hit-testable UIKit view when it should not capture touches.

This allows toast-style popups (TopPopup with clear overlay and
tapOutsideToDismissPopup(false)) to display without blocking user
interaction with the app content behind them.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant