swift – 如何覆盖初始UIViewController的特征集合? (与故事板)

前端之家收集整理的这篇文章主要介绍了swift – 如何覆盖初始UIViewController的特征集合? (与故事板)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个针对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一起使用.

它有效,但我仍然认为这是一个很好的方式来存档这个目标.

我的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:

现在它也适合你.如果您发现更好的方法或任何缺陷,请告诉我.

原文链接:https://www.f2er.com/swift/320245.html

猜你在找的Swift相关文章