iOS 8 - UIWindow 方向总是纵向的

Posted

技术标签:

【中文标题】iOS 8 - UIWindow 方向总是纵向的【英文标题】:iOS 8 - UIWindow Orientation Is Always Portrait 【发布时间】:2014-11-13 18:34:51 【问题描述】:

我正在将 ios 6 应用程序更新到 iOS 8 (iPad),并且我创建的任何新 UIWindows 始终以纵向模式显示。该应用最初支持纵向和横向方向,但现在仅支持横向。

我已将项目文件中支持的方向更改为横向左和横向右。正如预期的那样,整个 UI 以横向显示,但是当我创建一个新的 UIWindow 时,它以纵向显示。新的UIWindow 的框架与屏幕的框架完全匹配,所以我无法想象它为什么/如何以纵向模式显示。

以下代码是我用来创建和显示新的UIWindow,它充当模态:

var modalWindow:UIWindow = UIWindow(frame: self.view.window!.bounds)

modalWindow.backgroundColor = UIColor.blackColor().colorWithAlphaComponent(0.66)
modalWindow.hidden = false
modalWindow.windowLevel = (UIWindowLevelStatusBar + 1)

modalWindow.addSubview(customView)    

modalWindow.makeKeyAndVisible()

我已经为此苦苦挣扎了几个小时; UIWindow 不应该默认处于横向模式,因为该应用只支持横向方向吗?

对于如何解决此问题的任何建议,我将不胜感激。

编辑:

我刚刚创建了一个仅支持横向左和横向右的新测试应用程序,问题也出现在那里。这是一个错误吗?我似乎无法理解为什么 UIWindow 在处于横向模式时会认为应用处于纵向模式。

【问题讨论】:

您是仅支持 iOS 8+ 还是支持 iOS 7?如果是,你能在那个模拟器上测试它吗?我怀疑它会起作用,我知道为什么。 部署目标是iOS 8.0,但我的计划是支持iOS 7+和iOS 8+。我刚刚尝试将部署目标更改为 iOS 7.0,而 UIWindow 仍处于纵向模式。这就是你所说的“那个模拟器”吗? 也许退后一步,您为什么使用 UIWindows 进行模态演示?在 iOS 7 中,为自定义模式呈现提供了出色的新 API。我建议先检查一下:developer.apple.com/library/IOs/documentation/UIKit/Reference/… 我正在使用 UIWindows,因为我正在使用自定义视图而不是单独的视图控制器。我还想将自定义视图放置在屏幕上的任何位置。 不,这不是我所说的那个模拟器的意思。您需要从 Xcode Settings -> Downloads 下载 iOS 7.1 模拟器。无论如何,问题是在 iOS 8 中,UIScreen 和主窗口返回基于方向的边界和框架。以前,您总是会以纵向方式获取/设置方向,现在这取决于您的方向。我相信这是问题所在。 【参考方案1】:

编辑(2015 年 7 月 2 日)

这个答案在 iOS 8.3+ 和可能的 iOS 8 以前的版本中中断。我不建议任何人使用它,特别是因为不能保证它在未来的 iOS 版本中有效。

我的新解决方案使用UIViewController 的标准presentViewController 方法。我初始化UIViewController,将我的自定义模态View 添加为UIViewController 的子视图,然后使用约束定位模态View。像魅力一样工作!


原答案

我离开了一段时间,但决定今天回来。我最终将模态窗口旋转 -90 度,因为它会自动旋转 90 度以纵向显示。我还为模态窗口的宽度和高度添加了一个小计算,以支持 iOS 7 和 iOS 8。这是我的新代码:

// Get the screen size
var screenSize:CGSize = UIScreen.mainScreen().bounds.size

// Use the larger value of the width and the height since the width should be larger in Landscape
// This is needed to support iOS 7 since iOS 8 changed how the screen bounds are calculated
var widthToUse:CGFloat = (screenSize.width > screenSize.height) ? screenSize.width : screenSize.height

// Use the remaining value (width or height) as the height
var heightToUse:CGFloat = (widthToUse == screenSize.width ? screenSize.height : screenSize.width)

// Create a new modal window, which will take up the entire space of the screen
var modalWindow:UIWindow = UIWindow(frame: CGRect(x: 0, y: 0, width: widthToUse, height: heightToUse))

modalWindow.backgroundColor = UIColor.blackColor().colorWithAlphaComponent(0.66)
modalWindow.hidden = false
modalWindow.windowLevel = (UIWindowLevelStatusBar + 1)

modalWindow.addSubview(customView)    

// Create a -90 degree transform since the modal is always displayed in portrait for some reason
var newTransform:CGAffineTransform = CGAffineTransformMakeRotation(CGFloat(-M_PI / 2))

// Set the transform on the modal window
modalWindow.transform = newTransform

// Set the X and Y position of the modal window to 0
modalWindow.frame.origin.x = 0
modalWindow.frame.origin.y = 0

modalWindow.makeKeyAndVisible()

如上所述,这在 iOS 7+ 和 iOS 8+ 上都非常有效!使用子视图时,请注意模式的 widthheight 值会切换,因为它以纵向显示。因此,如果您想将子视图水平居中,请使用模态窗口的height 和子视图的width,而不是两个视图的width

【讨论】:

嗨,我也有同样的问题。我创建了一个自定义 taost 消息并将其添加到自定义 UIWindow。一切都很好。但它仅在 iPad3 (iOS 8.3) 横向模式下失败。有什么想法吗?

以上是关于iOS 8 - UIWindow 方向总是纵向的的主要内容,如果未能解决你的问题,请参考以下文章

iOS App:窗口旋转总是纵向而不是横向

iPhone - UIWindow 根据当前方向旋转?

iOS 8 - 关闭全屏 AVPlayerViewController 时将方向更改回纵向

应用程序中多个 UIWindow 的最佳实践

状态栏与 UIWindow 分开旋转

iOS 8 unwind segue 导致方向错误