I have two UIWindows on the screen and one is behind the other. is there a way to handle the user touch with the window that is behind?
Thanks
You should just be able to disable it like any UIView.
UIWindow *secondWindow = [[UIWindow alloc] initWithFrame:<#frame#>];
[secondWindow setUserInteractionEnabled:NO];
iOS looks by default first which window is touched, if multiple windows are in the touch area it picks the top one (based on window level, z index)
next it will call hitTest(_ point: CGPoint, with event: UIEvent) -> UIView?
on the window that the os thinks is touched.
If your views in that window might return nil (no view could be touched in that window, or you have overridden the hitTest) then the window will return it self.
To solve this you will need to subclass UIWindow
and override the hitTest function. If the view returned from the super.hitTest_:with:)
is nil or self // the window
then you might choose to delegate to another window. Pay attention to the fact that the window that was touched might have another coordinate space then the window that you will delegate to.
Example:
internal final class CustomWindow: UIWindow {
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
if let view = super.hitTest(point, with: event), view != self {
return view
}
guard let keyWindow = UIApplication.shared.keyWindow else {
return nil
}
return keyWindow.hitTest(keyWindow.convert(point, from: self), with: event)
}
}
You will only be able to accept touch events on one UIWindow
at a time. The UIWindow
that accepts events is called the keyWindow
.
[behindWindow makeKeyAndVisible];
Your foreground UIWindow
will remain visible, but your behindWindow
will be receiving events.
Thanks, but i just found the way:
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
for (UIWindow *win in [[UIApplication sharedApplication] windows]) {
if (win.tag != self.tag) {
return [win hitTest:point withEvent:event];
}
}
return nil;
}