查看所有内容:UIWindow 子视图 VS UIViewController 子视图 [英] View on top of everything: UIWindow subview VS UIViewController subview

查看:20
本文介绍了查看所有内容:UIWindow 子视图 VS UIViewController 子视图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为了像 UIAlertView 的行为那样在所有视图之上制作 UIView,我看到的最好方法是将它放在应用程序窗口中,即通过将视图添加到:

In order to make a UIView on top of all views like the behavior of UIAlertView, the best way I see is by putting it in the app window, which is by adding the view to:

[[[UIApplication sharedApplication] delegate] window]

但是,我发现的缺点是它不会自动轮换.为了让它旋转,最好的方法是在当前的 AppDelegate window.navigationController/rootViewController 上添加视图,但是,这样做不会不再凌驾于一切之上.假设当视图正在显示并且有一个 modalViewController 弹出时,模态视图肯定会覆盖视图.

However, the downside I found is that it doesn't automatically take in rotation. In order for it to take in rotation, the best way to do is by adding the view on current AppDelegate window.navigationController/rootViewController, however, by doing this it will no longer be on top of everything. Let say when view is displaying and there is a modalViewController popup, the modal view will certainly cover up the view.

我的问题是,是否可以将子视图添加到最顶部的窗口支持方向?在这种情况下我需要两套 Nib 文件吗?UIAlertView 如何神奇地结合最顶层的 &方向支持?当我查看 UIAlertView.h 时,我看到实际上有 2 个 UIWindows,一个叫做 originalWindow,另一个叫做 dimWindow.有没有可以找到 UIAlertView.m 的源代码的地方?

My question is, is it possible to add subview to the top most window and support orientation? Do I need two set of Nib file in this case? How UIAlertView does the magic to combine the topmost & orientation support? When I look into the UIAlertView.h, I see there is actually 2 UIWindows, once is called originalWindow and another called dimWindow. Is there a place where I can find the source code for UIAlertView.m?

推荐答案

我发现的最佳解决方案是创建一个透明的容器视图,将该容器添加到窗口中,然后将您的警报放置在该容器内.然后,您可以注册 UIApplicationWillChangeStatusBarOrientationNotification 以接收旋转事件并转换容器;这允许您独立操作警报的框架:

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);
     }];
}

如果你真的想要,你可以创建一个全新的窗口,其 windowLevel 属性设置为 UIWindowLevelAlert,这将保证该窗口保持在所有其他视图之上,包括键盘,但窗口管理有点棘手.上述解决方案应该足以满足大多数需求.

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.

简单地将视图控制器的视图添加到窗口的问题在于,不能保证接收所有旋转和 view[Will|Did][Disa|A]ppear: 消息,除非它通过根视图控制器上的 addChildViewController: 添加到视图控制器 hierarchy.

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.

这篇关于查看所有内容:UIWindow 子视图 VS UIViewController 子视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆