在iOS 13中覆盖traitCollection

时间:2019-12-28 10:11:11

标签: ios swift uitabbarcontroller uitraitcollection

在我的初始视图控制器中,我有一个UITabbarController作为子视图控制器。

我想让UITabbarController与traitCollection一起显示其UITabbar,该traitCollection具有Compact的horizo​​ntalSizeClass,以便在标签栏中,图像和标题看起来是垂直对齐的,而不是并排放置。

iOS13现在不支持覆盖UITabbarController的traitCollection getter, Xcode发出以下警告。

        override var traitCollection: UITraitCollection{
            let current = super.traitCollection
            let compact = UITraitCollection(horizontalSizeClass: .compact)
            return UITraitCollection(traitsFrom: [current, compact])
        }
  

MyTabbarController类重写-traitCollection getter,这不受支持。如果要覆盖特征,则必须使用适当的API。

研究了合适的API之后,我发现了

open func setOverrideTraitCollection(_ collection: UITraitCollection?, forChild childViewController: UIViewController)

实现此功能后,我可以覆盖myTabbarController的特征收集,但仅在视图更改方向之后。仅当我将viewWillTransition重写为method时,此API才有效。

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
        super.viewWillTransition(to: size, with: coordinator)
        let currentTC = traitCollection
        let compactTC = UITraitCollection(horizontalSizeClass: .compact)
        let custom = UITraitCollection(traitsFrom: [currentTC, compactTC])
        print("ovverride trait collections before transition")
        setOverrideTraitCollection(custom, forChild: tabController)
    }

仅在旋转设备时我才能覆盖特征。如果我尝试在任何其他视图控制器生命周期方法中覆盖特征集,则此API无法正常工作。最初加载视图时如何覆盖traitCollection? 我尝试在初始视图控制器的viewDidLoad()方法中使用相同的代码,但没有效果。

1 个答案:

答案 0 :(得分:0)

我不确定OP是否能正常工作,但最近遇到了同一问题。就我而言,我需要在iPhone和iPad上对待设备方向相同,尤其是将纵向尺寸类别设置为.compact(纵向)。

因为setOverrideTraitCollection()仅适用于子视图控制器,所以我必须将“主”视图控制器嵌入另一个视图控制器(称为“根”视图控制器)中,并在根视图中处理特征覆盖控制器。正如OP所暗示的,这需要在应用启动时以及方向改变时发生。就我而言,我可以在prepareForSegue中执行启动代码。不确定为什么将代码放入viewDidLoad()对OP不起作用-可能是因为他没有为子视图控制器的视图调用setNeedsLayout()。

这是我的根视图控制器代码:

class RootViewController: UIViewController {

    var masterViewController: MasterViewController?

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "MasterViewSegue" {
            masterViewController = segue.destination as? MasterViewController
            updateMasterViewTraits(for: CGSize(width: view.bounds.width, height: view.bounds.height))
        }
    }

    override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
        super.viewWillTransition(to: size, with: coordinator)
        updateMasterViewTraits(for: size)
    }

    func updateMasterViewTraits(for size: CGSize) {
        var orientationTraits: UITraitCollection
        if size.width < size.height {
            orientationTraits = UITraitCollection(traitsFrom:[UITraitCollection(horizontalSizeClass: .compact), UITraitCollection(verticalSizeClass: .regular)])
        } else {
            orientationTraits = UITraitCollection(traitsFrom:[UITraitCollection(horizontalSizeClass: .regular), UITraitCollection(verticalSizeClass: .compact)])
        }
        let traits = UITraitCollection(traitsFrom: [traitCollection, orientationTraits])
        setOverrideTraitCollection(traits, forChild: masterViewController!)
        masterViewController!.view.setNeedsLayout()
    }

}