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 shouldAutorotate
值 true
,但是 supportedInterfaceOrientations
应该只是纵向。
为什么需要它?
当您从另一个处于横向模式的 RotateViewController 返回(通过使用 popViewController
或 dismissViewController
)您的 FixedViewController(仅支持纵向模式)时,它应该自动旋转以返回纵向模式
我正在编写一个 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 shouldAutorotate
值 true
,但是 supportedInterfaceOrientations
应该只是纵向。
为什么需要它?
当您从另一个处于横向模式的 RotateViewController 返回(通过使用 popViewController
或 dismissViewController
)您的 FixedViewController(仅支持纵向模式)时,它应该自动旋转以返回纵向模式