How to differentiate top windows in iOS8?

2019-08-11 02:03发布

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 UITextEffectsWindows 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 UIWindows 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条回答
Melony?
2楼-- · 2019-08-11 03:00

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.
查看更多
登录 后发表回答