在iOS 8/9中根据设备方向更改ViewController
在iOS 8/9中,基于设备方向的两个视图控制器之间的首选方式是什么? 我想要构build一个横向显示的乐器。 在肖像我想显示应用程序的设置。
在AppDelegate.swift里面的“didFinishLaunchingWithOptions”函数中我把:
NSNotificationCenter.defaultCenter().addObserver(self, selector: "rotated", name: UIDeviceOrientationDidChangeNotification, object: nil)
然后在AppDelegate类中放入以下函数:
func rotated(){ if(UIDeviceOrientationIsLandscape(UIDevice.currentDevice().orientation){ println("landscape") } if(UIDeviceOrientationIsPortrait(UIDevice.currentDevice().orientation)){ println("Portrait") } }
或者你可以使用这个:
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) { if UIDevice.currentDevice().orientation.isLandscape.boolValue { println("landscape") } else { println("portraight") } }
这是我为iOS 9创build的机制,但是这也适用于iOS 8。
import UIKit extension CGSize { static func minMaxSize(size: CGSize) -> CGSize { return CGSize(width: size.minValue(), height: size.maxValue()) } static func maxMinSize(size: CGSize) -> CGSize { return CGSize(width: size.maxValue(), height: size.minValue()) } func minValue() -> CGFloat { return min(self.width, self.height) } func maxValue() -> CGFloat { return max(self.width, self.height) } } extension UIScreen { func isPortrait() -> Bool { return self.bounds.width < self.bounds.height } } class BaseViewController: UIViewController { var horizontalConstraints = [NSLayoutConstraint]() var verticalConstraints = [NSLayoutConstraint]() private lazy var _isPortrait: Bool = UIScreen.mainScreen().isPortrait() func isPortrait() -> Bool { if let parentViewController = self.parentViewController as? BaseViewController { return parentViewController.isPortrait() } return _isPortrait } override func loadView() { self.view = UIView() } override func viewDidLoad() { super.viewDidLoad() self.addViewController() self.addLayoutGuides() self.setupLayoutGuides() self.addSubViews() self.setupSubViews() } func addViewController() { /* override point */ } func addLayoutGuides() { /* override point */ } func setupLayoutGuides() { /* override point */ } func addSubViews() { /* override point */ } func setupSubViews() { /* override point */ } private func applyConstraints() { self.willApplyConstraints() self.isPortrait() ? self.applyVerticalConstrains() : self.applyHorizontalConstrains() self.didApllyedConstraints() } func willApplyConstraints() { /* override point */ } func applyVerticalConstrains() { /* override point */ } func applyHorizontalConstrains() { /* override point */ } func didApllyedConstraints() { /* override point */ override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) { if let superView = self.view.superview { if superView.isKindOfClass(UIWindow.self) && self.parentViewController == nil { if CGSize.minMaxSize(size) == CGSize.minMaxSize(UIScreen.mainScreen().bounds.size) { _isPortrait = size.width < size.height } } } super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator) self.applyConstraints() } }
至less我假设子viewController将永远不会触及inheritance的private _isPortrait
,因为它是lazy
。 只有rootViewController
的顶层视图可以设置这个属性。 检查完成后调用super viewWillTransitionToSize
函数。 因此,如果在rootViewController
上设置了该值,则在调用viewWillTransitionToSize
函数时,所有子viewController都将具有正确的值。 这是必须完成的,因为你不能依赖子viewController视图的大小,但是至less你可以相信你的rootViewController是全屏的。 希望能以某种方式帮助别人。
所以我的RootViewController
现在可能看起来像这样。
class RootViewController: BaseViewController { override func addViewController() { /* add child view controller here so they can receive callbacks */ } override func addSubViews() { /* add your subviews here in a way you like so you can play with AutoLayout as you wish */ } override func setupSubViews() { /* setup up your views here and always activate vertical constraints here */ /* because iOS will always initialize in portrait even if launched in landscape */ /* deactivate your horizontal constrains and put them inside the array */ /* add vertical constraints to the vertical array; other constraints can be active */ /* without the need to be added somewhere */ } override func willApplyConstraints() { /* deactivate all constrains */ NSLayoutConstraint.deactivateConstraints(self.verticalConstraints) NSLayoutConstraint.deactivateConstraints(self.horizontalConstraints) } override func applyVerticalConstrains() { NSLayoutConstraint.activateConstraints(self.verticalConstraints) } override func applyHorizontalConstrains() { NSLayoutConstraint.activateConstraints(self.horizontalConstraints) } override func didApllyedConstraints() { /* force layouting if needed */ self.view.layoutIfNeeded() } }
更新(Xcode 7 – OS X 10.11.1testing版):对于iPadtesting,使用iPad 2或iPad Retina模拟器,因为Air 1/2与AutoLayout有关。 所有的模拟器都会产生这个消息: <CATransformLayer: 0x790af320> - changing property masksToBounds in transform-only layer, will have no effect
- 移动SearchBar表格视图
- 当广告载入失败时,在Swift中隐藏iAd ADBannerView – 没有委托或委托没有实现didFailToReceiveAdWithError
- Domain = kCFErrorDomainCFNetwork Code = 303这个错误代码是什么意思?
- Xcode 6.3在项目重命名上崩溃
- 如何确定是否编译Xcode中的64位iOS
- ALAssetsLibrary太慢 – Objective-C
- 在iOS上的刻度线水平滑块
- 当我将UIPanGestureRecognizer和自动布局结合在一起时,我的UIViews变得糟糕透顶
- 尝试将存档提交到App Store时出现各种ITMS错误