7

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

我想UITabbarController显示它UITabbar的 traitCollection 具有紧凑的 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 覆盖为方法时,此 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()我的初始视图控制器的方法中使用相同的代码,但它没有效果。

4

1 回答 1

0

我不确定 OP 是否可以正常工作,但我最近遇到了同样的问题。就我而言,我需要将 iPhone 和 iPad 的设备方向视为相同,特别是在纵向方向中将 Horizo​​ntalSizeClass 设置为 .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()
    }

}
于 2020-05-25T12:58:15.530 回答