Симулятор Xcode не вызывает traitCollectionDidChange

Я переопределяю traitCollectionDidChange(_), чтобы обновить мои компактные и обычные ограничения. Когда я тестирую это на устройстве, вращая ограничения, они обновляются правильно. Однако, когда я пытаюсь протестировать тот же код в симуляторе, ничего не происходит. Я вставил операторы печати и вижу, что при вращении симулятора ничего не происходит. Это баг или нужно что-то специально делать для симулятора?

Заранее спасибо. Я использую Xcode 8.2.1, кстати.

Это мой код:

    private var compactConstraints: [NSLayoutConstraint] = []
    private var regularConstraints: [NSLayoutConstraint] = []
    private var sharedConstraints: [NSLayoutConstraint] = []
    ...
    override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {

        super.traitCollectionDidChange(previousTraitCollection)

        if (!sharedConstraints[0].isActive) {
            // activating shared constraints
            NSLayoutConstraint.activate(sharedConstraints)
        }


        if (self.traitCollection.containsTraits(in: UITraitCollection(horizontalSizeClass: UIUserInterfaceSizeClass.compact))) {

            print("going to activate: compact")
            if regularConstraints.count > 0 && regularConstraints[0].isActive {
                NSLayoutConstraint.deactivate(regularConstraints)
            }
            // activating compact constraints
            NSLayoutConstraint.activate(compactConstraints)
        } else {
            print("going to activate: regular")
            if compactConstraints.count > 0 && compactConstraints[0].isActive {
                NSLayoutConstraint.deactivate(compactConstraints)
            }
            // activating regular constraints
            NSLayoutConstraint.activate(regularConstraints)
        }

    }

Вывод консоли выглядит следующим образом:

[launch app]
`going to activate: compact`
[rotate the simulator with ⌘ arrow key]
`going to activate: compact`

Небольшое обновление, основанное на вопросе hoshy: я использую симулятор с устройствами iPhone. В частности, iPhone SE.


person Joseph    schedule 20.01.2017    source источник


Ответы (2)


horizontalSizeClass равно Compact для обеих ориентаций. verticalSizeClass — это regular для portrait и Compact для landscape для iPhone SE. Вы можете изменить эту строку

if (traitCollection.containsTraits(in: UITraitCollection(verticalSizeClass: .compact))) {

или просто

if traitCollection.verticalSizeClass == .compact {

Вы также можете использовать viewWillTransitionToSize:withTransitionCoordinator:, если вам нужна анимация для запуска вместе с анимацией изменения размера.

Создание адаптивного интерфейса от разработчика Apple

Если ограничений автоматического макета недостаточно для достижения желаемого вида, вы можете использовать метод viewWillTransitionToSize:withTransitionCoordinator:, чтобы внести изменения в макет. Вы также можете использовать этот метод для создания дополнительных анимаций, которые будут выполняться вместе с анимациями изменения размера. Например, во время поворота интерфейса вы можете использовать свойство targetTransform координатора перехода, чтобы создать матрицу встречного поворота для частей вашего интерфейса.

person Warif Akhand Rishi    schedule 23.01.2017
comment
Спасибо - так очевидно. :-) Я адаптировал оператор if-else для проверки как вертикального, так и горизонтального размеров классов. Таким образом, я могу лучше справляться с iPad. - person Joseph; 23.01.2017

Может ли быть так, что ваше реальное тестовое устройство — это iPhone, а ваш симулятор — iPad? Метод traitCollectionDidChange не будет вызываться для последнего, так как обе ориентации будут «обычными».

person hoshy    schedule 21.01.2017
comment
В качестве симулятора я выбрал iPhone SE. - person Joseph; 21.01.2017