переопределить traitCollection в iOS 13

В моем начальном контроллере представления у меня есть UITabbarController в качестве дочернего контроллера представления.

Я хочу, чтобы UITabbarController отображал свой UITabbar с traitCollection, имеющим horizontalSizeClass of Compact, чтобы на панели вкладок изображение и заголовок отображались вертикально, а не рядом.

Переопределение геттера traitCollection UITabbarController теперь не поддерживается в iOS13, Xcode выдает предупреждение ниже.

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

Класс MyTabbarController переопределяет метод получения -traitCollection, который не поддерживается. Если вы пытаетесь переопределить черты, вы должны использовать соответствующий API.

После исследования соответствующего API я нашел

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

После реализации этого я могу переопределить коллекцию признаков myTabbarController, но только после того, как представление изменило ориентацию. Этот API работает только в том случае, если я переопределяю метод viewWillTransition.

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() моего начального контроллера представления, но это не дало никакого эффекта.


person FE_Tech    schedule 28.12.2019    source источник


Ответы (1)


Я не уверен, что ОП когда-либо работал, но недавно я столкнулся с той же проблемой. В моем случае мне нужно обрабатывать ориентацию устройства одинаково для iPhone и iPad и, в частности, установить для HorizontalSizeClass значение .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()
    }

}
person bill.westland    schedule 25.05.2020