iPhone - UIWindow 根据当前方向旋转?
Posted
技术标签:
【中文标题】iPhone - UIWindow 根据当前方向旋转?【英文标题】:iPhone - UIWindow rotating depending on current orientation? 【发布时间】:2011-07-14 17:41:52 【问题描述】:我正在向我的应用程序添加一个额外的 UIWindow。 我的主窗口可以正确旋转,但我添加的这个附加窗口没有旋转。
根据当前设备方向旋转 UIWindow 的最佳方式是什么?
【问题讨论】:
为什么要添加另一个 UIWindow? “每个 ios 应用程序都需要至少一个窗口——UIWindow 类的一个实例——有些可能包含多个窗口。” (View Programming Guide for iOS) 这并不能回答为什么人们会想要另一个窗口的问题。最常见的用例似乎是视频输出。 迷人。但我读了这个问题。我在回复 Moshe。 @Moshe 创建另一个窗口是尝试将内容放置在 UIPopoverController(它本身创建一个单独的 UIWindow)“上方”时的一种常见技术。从 UIPopoverController 拖放是典型的例子 【参考方案1】:你需要为 UIWindow 滚动你自己的。
监听UIApplicationDidChangeStatusBarFrameNotification
通知,然后设置状态栏变化时的变换。
您可以从-[UIApplication statusBarOrientation]
读取当前方向,并像这样计算变换:
#define DegreesToRadians(degrees) (degrees * M_PI / 180)
- (CGAffineTransform)transformForOrientation:(UIInterfaceOrientation)orientation
switch (orientation)
case UIInterfaceOrientationLandscapeLeft:
return CGAffineTransformMakeRotation(-DegreesToRadians(90));
case UIInterfaceOrientationLandscapeRight:
return CGAffineTransformMakeRotation(DegreesToRadians(90));
case UIInterfaceOrientationPortraitUpsideDown:
return CGAffineTransformMakeRotation(DegreesToRadians(180));
case UIInterfaceOrientationPortrait:
default:
return CGAffineTransformMakeRotation(DegreesToRadians(0));
- (void)statusBarDidChangeFrame:(NSNotification *)notification
UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
[self setTransform:[self transformForOrientation:orientation]];
根据您的窗口大小,您可能还需要更新框架。
【讨论】:
@morten-fast 感谢您的提示。但我不知道如何处理轮换的协调系统......x
变成y
和width
变成height
?还是没有?
好的。我做了一些研究,似乎应用程序的主要UIWindow
处理方向变化而不旋转......所以应该有其他方法???有人吗?
@oleynikd 在 iOS8 及更高版本上,如果您将 Windows rootViewController 设置为它正在呈现的 UIViewController,它将为您处理旋转(尽管我遇到了一些错误 - 特别是在我的启动应用程序的视图控制器,如果我弹出键盘)【参考方案2】:
只需创建一个带有自己的UIView
的UIViewController
,将其作为rootViewController
分配给您的窗口,并将所有进一步的用户界面添加到控制器的视图(而不是直接添加到窗口),控制器将处理所有轮换为您服务:
UIApplication * app = [UIApplication sharedApplication];
UIWindow * appWindow = app.delegate.window;
UIWindow * newWindow = [[UIWindow alloc] initWithFrame:appWindow.frame];
UIView * newView = [[UIView alloc] initWithFrame:appWindow.frame];
UIViewController * viewctrl = [[UIViewController alloc] init];
viewctrl.view = newView;
newWindow.rootViewController = viewctrl;
// Now add all your UI elements to newView, not newWindow.
// viewctrl takes care of all device rotations for you.
[newWindow makeKeyAndVisible];
// Or just newWindow.hidden = NO if it shall not become key
当然,同样的设置也可以在界面生成器中创建而无需一行代码(除了在显示窗口之前将帧大小设置为填满整个屏幕)。
【讨论】:
只是好奇,但你为什么说要将所有子视图添加到 newView 而不是 newWindow? @CoDEFRo 因为旋转是由 ViewController (viewctrl
) 执行的,而这个 ViewController 只旋转它控制的视图(即newView
),然后它将递归地旋转它的所有子视图。如果您将它们直接添加到newWindow
,那么您的视图不会被 ViewController 旋转,您将不得不再次手动旋转它们(当您旋转设备时,UIWindow 不会旋转任何视图,它不会)甚至不旋转)。【参考方案3】:
您需要设置新窗口的rootViewController。然后窗口的子视图将正确旋转。
myNewWindow!.rootViewController = self
然后您可以在旋转方法中更改帧。
例如(在 ios8 中快速)
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator)
customAlertView.frame = UIScreen.mainScreen().bounds
【讨论】:
【参考方案4】:我不知道你对窗口做了什么。但根控制器需要以 YES 响应 shouldAutorotate。
【讨论】:
谢谢,但该方法仅适用于 UIVievController,我正在尝试旋转 UIWindow【参考方案5】:您可以为您的 UIWindow 设置 rootController。例如:
fileprivate(set) var bottonOverlayWindow = UIWindow()
self.bottonOverlayWindow.rootViewController = self;
// 'self' 将是您在其上添加 UIWindow 视图的 ViewController。所以每当你 ViewController 改变方向时,你的窗口视图也会改变它的方向。
如果您遇到任何问题,请告诉我。
【讨论】:
以上是关于iPhone - UIWindow 根据当前方向旋转?的主要内容,如果未能解决你的问题,请参考以下文章