iOS8中设备旋转后的ViewController偏移量

Posted

技术标签:

【中文标题】iOS8中设备旋转后的ViewController偏移量【英文标题】:ViewController offset after device rotation in iOS8 【发布时间】:2014-11-07 23:34:47 【问题描述】:

我在 ios8 中运行的遗留代码遇到了一个奇怪的问题。该代码最初是在 iOS6 之前编写的,故事板之前(使用 nib)并且在 iOS7 上运行没有问题。但是,在 iOS8 上运行时开始出现奇怪的行为。

应用程序设置为仅在横向(左侧或右侧)运行。因此它应该支持从横向左到横向的自动旋转。第一个问题是初始视图控制器是纵向加载的,并且一侧被切断。此问题已通过 AppDelegate 中的以下代码得到解决:

self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
[self.window setFrame:[[UIScreen mainScreen] bounds]];

更改这些调用的顺序允许视图控制器以正确的方向加载,并且不会影响在 iOS7 中运行的应用程序。但是,现在当设备旋转 180 度时,我得到以下结果。看图片...

这是初始加载时的应用程序:

在旋转 180 度后,我得到了这种偏移效果:

关于如何解决这个问题的任何想法?同样,在 iOS7 或更早版本中一切正常。谢谢!

【问题讨论】:

好吧,这不是“最干净”的解决方案,但应该可以解决问题,您可以使用一些在旋转之前/之后调用的旋转方法将视图控制器的原点设置为(0, 0)。看看viewWillTransitionToSize:withTransitionCoordinator: 方法。 您似乎不想将第二张图片作为输出。您是否尝试过使用自动布局? 【参考方案1】:

我在iOS 8刚出现的时候也遇到过和你一样的问题,和开窗咒语无关!它与您的 Info.plist 有关。 Info.plist 中列出的 first 方向必须是根视图控制器实际允许的方向。

所以,假设您的根视图控制器只允许横向。然后,如果您的 Info.plist 如下所示,您得到您描述的问题:

<key>UISupportedInterfaceOrientations</key>
<array>
    <string>UIInterfaceOrientationPortrait</string>
    <string>UIInterfaceOrientationLandscapeLeft</string>
    <string>UIInterfaceOrientationLandscapeRight</string>
</array>

看到错误了吗?肖像是第一位的。 没有。如果根视图控制器只允许横向,则横向方向之一必须先出现。

[您实际上可以看到我遇到问题,然后发现并报告解决方案,这里:https://***.com/a/24467576/341994]


另外,我想知道您是否正在做任何其他扰乱轮换系统的事情。请注意,旋转本身的性质,包括坐标系、旋转什么、何时旋转等,在 iOS 8 中完全改变了;这可能是 iOS 8 中最大的单一变化。因此,如果您有旧代码对旋转是什么进行了底层假设(例如,它涉及变换),那么该代码现在将中断。你没有在你的问题中显示任何这些,所以我无法提供你可能在做什么的细节。


最后,为了记录,正确的最小开头咒语是(这是 Swift 代码,但我相信你可以翻译):

func application(application: UIApplication, 
    didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool 

    self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
    self.window!.rootViewController = UIViewController() // or whatever it is
    self.window!.backgroundColor = UIColor.whiteColor()
    self.window!.makeKeyAndVisible()
    return true

【讨论】:

【参考方案2】:

您应该在视图控制器上使用一些自动布局约束,以便它粘在父容器的左/上和下。

【讨论】:

【参考方案3】:

这里有一些想法:

1) 用框架初始化你的窗口,之后不要设置

self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

2) 确保您的 rootViewController 视图的 autoresizingMask 为 FlexibleWidth+FlexibleHeight 并且您在其中的任何地方都没有灵活的边距。

3) 确保您的应用程序的目标明确只有在 General->Deployment Info 部分中您想要的方向。听起来您只能将其放入您想要的方向,但只需检查以确保!

【讨论】:

【参考方案4】:

在将我们的应用程序从 iOS 7.x 迁移到 iOS 8.4 时,我浪费了一整天的时间来解决类似的问题。设备旋转后视图的神秘偏移大小错误。

我们的应用程序使用 UITabBarController 作为 RootViewController,并且选项卡的数量可以动态变化。在 iPad 上,所有视图都支持所有方向。在 iPhone 上,只能旋转一个视图,所有其他视图都固定设置为纵向。因为视图的数量可以动态变化,所以我有一个属性 存储每个视图的可能方向。每次从 iOS 调用 UIViewController.supportedInterfaceOrientations() 时,我都会返回属性的内容。

在调试问题时,我注意到函数 UIViewController.supportedInterfaceOrientations() 在 AppDelegate 调用函数 UIWindow.MakeKeyAndVisible() 之后立即被调用。此时,我的代码没有机会初始化该属性,所以 UIViewController.suppoertedInterfaceOrientations() 返回 0 给 iOS。在我更改代码以便在调用 UIWindow.MakeKeyAndVisible() 之前初始化我的属性之后,神秘的 大小和偏移问题消失了!!!

我的结论:不要用错误或缺失的 UIViewController.supportedInterfaceOrientations() 函数弄乱 iOS ;-)

【讨论】:

以上是关于iOS8中设备旋转后的ViewController偏移量的主要内容,如果未能解决你的问题,请参考以下文章

在 iOS 8 中禁用 UIViewController 的旋转

使用swift iOS8通过代码将约束设置到Storyboard中的元素

如何使用点击手势(iOS8 / Swift)在 pageViewController 上显示/隐藏状态栏

无法在 iPad 上正确旋转翻译后的 UIView

未调用 iOS8 接口旋转方法

我可以为图像制作动画吗iOS8 LaunchScreen.xib