View on top of everything: UIWindow subview VS UIViewController subview View on top of everything: UIWindow subview VS UIViewController subview xcode xcode

View on top of everything: UIWindow subview VS UIViewController subview


The best solution I've found is to create a transparent container view, add that container to the window, and place your alert inside the container. You may then register for UIApplicationWillChangeStatusBarOrientationNotification to receive rotation events and transform the container; this allows you to independently manipulate the frame of the alert:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {     ...     self.container = [[UIView alloc] initWithFrame:self.window.bounds];     [self.container addSubview:self.alertView];     [self.window addSubview:self.container];     [[NSNotificationCenter defaultCenter] addObserver:self                                               selector:@selector(statusBarWillRotate:)                                                   name:UIApplicationWillChangeStatusBarOrientationNotification                                                 object:nil];     ...}...- (void)statusBarWillRotate:(NSNotification *)theNotification{    CGFloat rotation = 0;    switch ([notification[UIApplicationStatusBarOrientationUserInfoKey] intValue])    {        case UIInterfaceOrientationLandscapeLeft:            rotation = -M_PI_2;            break;        case UIInterfaceOrientationLandscapeRight:            rotation = M_PI_2;            break;        case UIInterfaceOrientationPortraitUpsideDown:            rotation = M_PI;            break;        case UIInterfaceOrientationPortrait:         default:            rotation = 0;            break;    }    CGAffineTransform rotationTransform = CGAffineTransformMakeRotation(rotation);    CGSize rotatedSize = CGRectApplyAffineTransform(self.window.bounds, rotationTransform).size;    [UIView animationWithDuration:[UIApplication sharedApplication].statusBarOrientationAnimationDuration                       animations:^{         self.container.transform = rotationTransform;         // Transform invalidates the frame, so use bounds/center         self.container.bounds = CGRectMake(0, 0, rotatedSize.width, rotatedSize.height);         self.container.center = CGPointMake(self.window.bounds.size.width / 2, self.window.bounds.size.height / 2);     }];}

You can, if you really want, create an entirely new window with its windowLevel property set to UIWindowLevelAlert, which will guarantee that the window remain above all other views, including the keyboard, but window management gets a littly tricky. The above solution should suffice for most needs.

The problem with simply adding a view controller's view to a window is that it is not guaranteed to receive all the rotation and view[Will|Did][Disa|A]ppear: messages unless it is added to the view controller hierarchy via addChildViewController: on the root view controller.


Only the first subview of UIWindow gets told about orientation changes. (< iOS8)

Your question is very similar to this one:

Multiple views in a UIWindow

As the answer there says, you can register for notifications of orientation changes and handle relayout of your 'on top' subview that way.


Here is a possible solution, I am explaining in a few steps.

  1. Start With a UIViewController inherited class instead of UIView, Lets say class named TopViewController inherited by UIViewController
  2. Since you you can not register device/interface rotation in UIView inherited class, the TopViewController class which is inherited from UIViewController has methods responding to View Rotation Events. Rotation events can be captured now.
  3. At last you can put the TopViewController view on the top of UIWindow by using the same method that you mentioned in your question .

    [[[[UIApplication sharedApplication] delegate] window] addSubview:(TopViewController object).view];

Hope this helps.