iOS ViewController 方向更改后布局不正确

iOS ViewController doesn't layout properly after orientation change

我正在编写一个 iOS 应用程序,其中包含一些固定(纵向)视图和一些方向相关的视图(纵向、左侧横向和右侧横向)。

视图包含在基于以下代码的自定义导航控制器中:

class CustomNavigationViewController: UINavigationController {
    override func supportedInterfaceOrientations() -> Int {
        return self.topViewController.supportedInterfaceOrientations()
    }

    override func shouldAutorotate() -> Bool {
        return self.topViewController.shouldAutorotate()
    }
}

我在导航子控制器中实现 supportedInterfaceOrientations()shouldAutorotate()

这是一个测试控制器

class TestViewController: UIViewController {
    var shouldRotate: Bool = false

    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
        self.shouldRotate = true
    }

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    convenience init(rotation shouldRotate: Bool) {
        self.init(nibName: "TestViewController", bundle: nil)
        self.shouldRotate = shouldRotate
    }

    override func supportedInterfaceOrientations() -> Int {
        if shouldRotate == false {
            return UIInterfaceOrientation.Portrait.rawValue
        } else {
            return super.supportedInterfaceOrientations()
        }
    }

    override func shouldAutorotate() -> Bool {
        return shouldRotate
    }

    override func didRotateFromInterfaceOrientation(fromInterfaceOrientation: UIInterfaceOrientation) {
        println("from: \(fromInterfaceOrientation.rawValue)")
    }

    @IBAction func buttonTapped(sender: AnyObject) {
        let newvc = TestViewController(rotation: true)
        self.navigationController?.pushViewController(newvc, animated: true)
    }
}

第一个控制器在 AppDelegate 中用 rotation: false 实例化。其他控制器使用 rotation: true 创建并在点击按钮后推送。

这是视图的屏幕截图:

如果我在第一个(可旋转的)之后改变控制器的方向,我会得到以下结果:

控制器 xib 使用自动布局,如果我在点击按钮之前旋转设备,它会按预期工作,视图会填满整个屏幕。

此外,如果我在 phone 处于横向状态时点击后退按钮,第一个视图将锁定在此状态:

我正在将应用程序部署到 iOS 8.

如何才能让第一个视图只有纵向,而其他视图在旋转后正确布局?

这可能无关紧要,因为它只是打印出一条调试消息,但不要忘记 didRotateFromInterfaceOrientation(_:) 在 iOS 8 中被贬值,viewWillTransitionToSize(_:withTransitionCoordinator:) 取代了它更改视图大小(包括旋转)的责任。

我认为您走在正确的轨道上,但不要同时覆盖 shouldAutorotate()supportedInterfaceOrientations(),而是只覆盖 supportedInterfaceOrientations().

我只是做了一个快速的 POC,看看它是否可行。我在创建视图控制器时没有设置标志(并使用 Swift 2),但你明白了:

class RotatingViewController: UIViewController {
    override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
        return UIInterfaceOrientationMask.All
    }
}

class FixedViewController: UIViewController {
    override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
        return UIInterfaceOrientationMask.Portrait
    }
}

class NavigationController: UINavigationController {
    override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
        return self.topViewController?.supportedInterfaceOrientations() ?? UIInterfaceOrientationMask.All
    }
}

我认为你的演示中发生的事情是,当你转换到一个固定的视图控制器时,你要求它进入纵向(它是)但不允许屏幕旋转回纵向模式。

所以.. 只需尝试删除 CustomNavigationViewController 中的 'shouldAutorotate()',看看是否可行。

问题是因为 shouldAutorotate return false。 您的 FixedViewController 应该 return shouldAutorotatetrue,但是 supportedInterfaceOrientations 应该只是纵向。

为什么需要它? 当您从另一个处于横向模式的 RotateViewController 返回(通过使用 popViewControllerdismissViewController)您的 FixedViewController(仅支持纵向模式)时,它应该自动旋转以返回纵向模式