I'm creating an overlay which will cover all displaying views on screen. This overlay always appears even in case rootViewController
changes, pushing or presenting.
My idea is
CustomWindow
which is a subclass of UIWindow
. After that replacing default window
of UIApplication
with CustomWindow
, create a new rootViewController
for my new window.CustomWindow
, I have an overlay
(is an UIView
). Overlay
have light gray color with an alpha and every event on overlay
will be pass through to below view.CustomWindow
add a new subview, i will bring overlay
to front. It's make sure overlay
will be on the top in every case.CustomWindow
@implementation CustomWindow
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
_overlay = [[UIView alloc] initWithFrame:self.bounds];
_overlay.userInteractionEnabled = NO;
_overlay.backgroundColor = [UIColor lightGrayColor];
_overlay.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self addSubview:_overlay];
}
return self;
}
- (void)didAddSubview:(UIView *)subview {
[super didAddSubview:subview];
[self bringSubviewToFront:_overlay];
}
@end
Everything works fine in every case even when pushing, presenting or changing rootViewController
.
Problem
But when i show an UIActivityViewController
, I can't click on any extensions which are displayed on UIActivityViewController
.
Magically
When i click outside of UIActivityViewController
or click on Cancel Button
, UIActivityViewController
is dismissed normally.
If i change color of overlay
to clearColor
, it works fine too.
My question is
How can i touch on extensions when i have overlay
on window and overlay
have a color ?
If i can't, can anyone tell me why it happens ? It's perfect when you can quote the reason from a document.
I'm pretty sure this doesn't relate to how i initialize UIActivityViewController
or the way i show UIActivityViewController
.
MORE
I found a problem quite similar to this problem on Android
. But i'm not sure because i haven't seen any official document about it from Apple. One more thing is when changing color to clearColor
can affect touch. So actually, i don't think they are same.
This is due to a UIRemoveView
(private) in the hierarchy. As best I can determine, your app cannot forward events directly to remote views. I suspect this is a security measure to prevent you from presenting the share dialog and automatically sending a touch event to it to do an external action the user didn't request. Remote views don't run in your application's process. The "Copy" button is interacted with across an XPC link.
This all means that if the remote view is covered by one of your views, there's no way (at least that I've found) to interact with it. You have to ensure that you're not covering it.
Actually doing that is simple. The thing that holds the remote view is called a UITransitionView
and is used for other OS-level things that you probably shouldn't be covering either. So don't:
- (void)didAddSubview:(UIView *)subview {
[super didAddSubview:subview];
if ([subview isKindOfClass:NSClassFromString(@"UITransitionView")]) {
// To raise it above your overlay;
// otherwise it's immediately above the view controller (below the overlay)
[self bringSubviewToFront:subview];
} else {
[self bringSubviewToFront:self.overlay];
}
}
But.... This requires you to talk about UITransitionView
in your code. This is both fragile, and possibly a forbidden use of private APIs.
Otherwise you'll have to wrap your UIActivityViewController requests with some call/notification that tells the window not to cover views until we're done (which you'll have to clear in the completion handler).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With