我有一个针对iOS8的应用程序,初始视图控制器是UISplitViewController.我使用故事板,以便它为我实例化一切.
由于我的设计,我需要SplitViewController在iPhone上以纵向模式显示主视图和详细视图.所以我正在寻找一种方法来覆盖这个UISplitViewController的特征集合.
我发现我可以使用
override func viewWillTransitionToSize(size: CGSize,withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator!) { ... }
但是,遗憾的是,只有方法可以覆盖子控制器特征集合:
setOverrideTraitCollection(collection: UITraitCollection!,forChildViewController childViewController: UIViewController!)
我不能在我的UISplitViewController子类中为self做到这一点.
我查看了Apple的示例应用程序Adaptive Photos.在这个应用程序中,作者使用特殊的TraitOverrideViewController作为root,并在他的viewController setter中使用一些魔法来使它全部工作.
这对我来说太可怕了.是否有任何方式来覆盖特征?或者如果没有,我如何设法使用与故事板相同的黑客?换句话说,如何以root用户身份注入一些viewController只是为了处理带故事板的UISplitViewController的特征?
好的,我希望有另一种解决方法,但是现在我只是将Apple示例中的代码转换为Swift并将其调整为与Storyboard一起使用.
原文链接:https://www.f2er.com/swift/320245.html它有效,但我仍然认为这是一个很好的方式来存档这个目标.
我的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 } }
要使其工作,您需要在故事板上添加一个新的UIViewController并使其成为初始.将show segue从它添加到您的真实控制器,如下所示:
您需要将segue命名为“toSplitVC”:
并将初始控制器设置为TraitOverride:
现在它也适合你.如果您发现更好的方法或任何缺陷,请告诉我.