问题
Following the strategy from this SO answer, in iOS 7 I could find the top window in my app like so:
UIWindow *topWindow = [[[UIApplication sharedApplication].windows sortedArrayUsingComparator:^NSComparisonResult(UIWindow *win1, UIWindow *win2) {
return win1.windowLevel - win2.windowLevel;
}] lastObject];
However, since iOS8 there may be one or more UITextEffectsWindow
s which may be the lastObject
in the above strategy. No good.
Initially I could run a predicate filter on the array of windows and test which windows are UIWindow
s like so:
NSPredicate *filter = [NSPredicate predicateWithBlock:^BOOL(id obj, NSDictionary *bind) {
return [obj isMemberOfClass:[UIWindow class]];
}];
However, the top UIWindow
may not be UIWindow
, but some subclass like NRWindow. Here is an example:
[[NRWindow class] isKindOfClass:[UIWindow class]]; // true
[[UITextEffectsWindow class] isKindOfClass:[UIWindow class]]; // true
My question is this: How can I safely differentiate/find the top UIWindow
subclass so I can do things like
[[topWindow rootViewController] presentViewController:mailComposer animated:YES completion:nil];
(Note: Testing for UITextEffectsWindow
directly is frowned upon, and [[UIApplication sharedApplication] keyWindow]
unfortunately isn't reliable.)
回答1:
I assume that you only want to present from windows that you have created. So you could:
- Write a subclass of UIWindow and use that when creating your windows. Then you can test for windows of that subclass.
- Add an associated object to all windows that are eligible for presenting a modal view. Then you can test for the associated object when searching for a window.
来源:https://stackoverflow.com/questions/31375915/how-to-differentiate-top-windows-in-ios8