Ok, I wish there was another way around this, but for now I just converted code from the Apple example to Swift and adjusted it to use with Storyboards.
It works, but I still believe it is an awful way to archive this goal.
My TraitOverride.swift:
import UIKit
class TraitOverride: UIViewController {
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
var forcedTraitCollection: UITraitCollection? {
didSet {
updateForcedTraitCollection()
}
}
override func viewDidLoad() {
setForcedTraitForSize(view.bounds.size)
}
var viewController: UIViewController? {
willSet {
if let previousVC = viewController {
if newValue !== previousVC {
previousVC.willMoveToParentViewController(nil)
setOverrideTraitCollection(nil, forChildViewController: previousVC)
previousVC.view.removeFromSuperview()
previousVC.removeFromParentViewController()
}
}
}
didSet {
if let vc = viewController {
addChildViewController(vc)
view.addSubview(vc.view)
vc.didMoveToParentViewController(self)
updateForcedTraitCollection()
}
}
}
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator!) {
setForcedTraitForSize(size)
super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
}
func setForcedTraitForSize (size: CGSize) {
let device = traitCollection.userInterfaceIdiom
var portrait: Bool {
if device == .Phone {
return size.width > 320
} else {
return size.width > 768
}
}
switch (device, portrait) {
case (.Phone, true):
forcedTraitCollection = UITraitCollection(horizontalSizeClass: .Regular)
case (.Pad, false):
forcedTraitCollection = UITraitCollection(horizontalSizeClass: .Compact)
default:
forcedTraitCollection = nil
}
}
func updateForcedTraitCollection() {
if let vc = viewController {
setOverrideTraitCollection(self.forcedTraitCollection, forChildViewController: vc)
}
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
performSegueWithIdentifier("toSplitVC", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
if segue.identifier == "toSplitVC" {
let destinationVC = segue.destinationViewController as UIViewController
viewController = destinationVC
}
}
override func shouldAutomaticallyForwardAppearanceMethods() -> Bool {
return true
}
override func shouldAutomaticallyForwardRotationMethods() -> Bool {
return true
}
}
To make it work you need to add a new UIViewController on the storyboard and made it the initial. Add show segue from it to your real controller like this:
You need to name the segue "toSplitVC":
and set initial controller to be TraitOverride:
Now it should work for you too. Let me know if you find a better way or any flaws in this one.
AAPLTraitOverrideViewController.m
is barely more than 20 lines of code. It should take you maybe 10 minutes to translate that into Swift and then you don't have to look at it again. – Mercury