xcode 查看所有内容:UIWindow 子视图 VS UIViewController 子视图
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8774495/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
View on top of everything: UIWindow subview VS UIViewController subview
提问by Zian Chen
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:
为了UIView
在所有视图之上创建一个像 的行为UIAlertView
,我看到的最好方法是将它放在应用程序窗口中,即将视图添加到:
[[[UIApplication sharedApplication] delegate] window]
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.
但是,我发现的缺点是它不会自动轮换。为了让它旋转,最好的方法是在当前 AppDelegate window.navigationController
/上添加视图rootViewController
,但是,通过这样做,它将不再位于一切之上。假设当视图正在显示并且有一个 modalViewController 弹出窗口时,模态视图肯定会覆盖视图。
My question is, is it possible to add subview to the top most window andsupport 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
?
我的问题是,是否可以将子视图添加到最顶部的窗口并支持方向?在这种情况下我需要两套 Nib 文件吗?UIAlertView
结合最顶层和方向支持的魔力如何?当我查看时UIAlertView.h
,我看到实际上有 2 个UIWindows
,一个被调用originalWindow
,另一个被调用dimWindow
。有没有可以找到源代码的地方UIAlertView.m
?
回答by Austin
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:
我发现的最佳解决方案是创建一个透明的容器视图,将该容器添加到窗口中,并将您的警报放在容器内。然后您可以注册UIApplicationWillChangeStatusBarOrientationNotification
接收旋转事件并转换容器;这允许您独立操作警报的框架:
- (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.
如果你真的想要,你可以创建一个全新的窗口,其windowLevel
属性设置为UIWindowLevelAlert
,这将保证窗口保持在所有其他视图之上,包括键盘,但窗口管理有点棘手。上述解决方案应该足以满足大多数需求。
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 hierarchyvia addChildViewController:
on the root view controller.
简单地将视图控制器的视图添加到窗口的问题在于,它不能保证接收所有旋转和view[Will|Did][Disa|A]ppear:
消息,除非通过根视图控制器将其添加到视图控制器层次结构中addChildViewController:
。
回答by occulus
Only the first subview of UIWindow
gets told about orientation changes. (< iOS8)
只有第一个子视图UIWindow
被告知方向变化。(< iOS8)
Your question is very similar to this one:
您的问题与此问题非常相似:
As the answer there says, you can register for notifications of orientation changes and handle relayout of your 'on top' subview that way.
正如那里的答案所说,您可以注册方向更改通知并以这种方式处理“顶部”子视图的重新布局。
回答by Rahul
Here is a possible solution, I am explaining in a few steps.
这是一个可能的解决方案,我将分几个步骤进行解释。
- Start With a
UIViewController
inherited class instead ofUIView
, Lets say class namedTopViewController
inherited byUIViewController
- Since you you can not register device/interface rotation in UIView inherited class, the
TopViewController
class which is inherited fromUIViewController
has methods responding to View Rotation Events. Rotation events can be captured now. At last you can put the
TopViewController
view on the top ofUIWindow
by using the same method that you mentioned in your question .[[[[UIApplication sharedApplication] delegate] window] addSubview:(TopViewController object).view];
- 从
UIViewController
继承的类而不是 开始UIView
,让我们说名为TopViewController
继承的类UIViewController
- 既然你不能在UIView的继承类注册设备/接口转动,
TopViewController
这是从继承的类UIViewController
有方法应对视图旋转活动。现在可以捕获旋转事件。 最后,您可以使用您在问题中提到的相同方法将
TopViewController
视图放在顶部UIWindow
。[[[[UIApplication sharedApplication] delegate] window] addSubview:(TopViewController object).view];
Hope this helps.
希望这可以帮助。