1

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.)

Community
  • 1
  • 1
Drakes
  • 23,254
  • 3
  • 51
  • 94

1 Answers1

0

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.
Mats
  • 8,528
  • 1
  • 29
  • 35
  • Thank you for your suggestion. Unfortunately I do not control which windows are created. In debugging one team may add an NRWindow, which the screenshot team may add another window with pretty overlays. – Drakes Jul 14 '15 at 04:33