iOS: ограничения прекращаются при возврате к контроллеру просмотра после изменения ориентации - PullRequest
0 голосов
/ 28 марта 2019

Привет, студент быстро учится здесь. На iPad я создавал специальное приложение для сегментированного элемента управления, где в портретной ориентации сегментированный элемент управления находится сверху, а в альбомной ориентации - слева. Сегментированный элемент управления реализуется путем встраивания collectionView в UIView. Это только помогает мне отделить методы источника данных / делегата от viewController. Содержимое отображается стандартным вложенным collectionView. Вот так:

portraitenter image description here

Мне удалось обработать поворот в этом контроллере представления без каких-либо предупреждений или ошибок. Я инициирую два массива ограничений для портретной и альбомной ориентации и деактивирую / активирую их в viewWillTransitionToSize по мере необходимости. Проблема возникает, когда: новый контроллер вида помещается на этот -> устройство поворачивается -> возвращается к этому контроллеру .

Поворот в портрет на новом контроллере представления и возврат назад вызывает ошибку « UICollectionViewFLowLayout не определено ». Поворот к ландшафту менее серьезен, он приводит к неправильному размеру представления коллекции контента. Как это:

Portrait bugLandscape bug

Ниже моя реализация viewWillTransitionToSize. Спасибо! Буду признателен за любые идеи.

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
    segmentedControl.collectionView.collectionViewLayout.invalidateLayout()
    segmentedControl.collectionView.reloadData()
    contentScroll.collectionViewLayout.invalidateLayout()
    contentScroll.reloadData()

    super.viewWillTransition(to: size, with: coordinator)

    NSLayoutConstraint.deactivate(p)    //deactivate constraints for portrait and landscape
    NSLayoutConstraint.deactivate(l)

    if isPortrait {
        if let layout = segmentedControl.collectionView.collectionViewLayout as? UICollectionViewFlowLayout {
            layout.scrollDirection = .horizontal
        }

        NSLayoutConstraint.activate(p)

        DispatchQueue.main.async {    //scrolling content and segmentedControl to their correct places
            self.jumpContentViewToIndex(tabIndex: self.targetIndex, animated: false)    
            self.segmentedControl.scrollAndUpdateIndex(to: self.targetIndex)
        }
    } else {
        if let layout = segmentedControl.collectionView.collectionViewLayout as? UICollectionViewFlowLayout {
            layout.scrollDirection = .vertical
        }

        NSLayoutConstraint.activate(l)

        DispatchQueue.main.async {    //scrolling content and segmentedControl to their correct places
            self.contentScroll.scrollToItem(at: IndexPath(item: 0, section: 0), at: .centeredHorizontally, animated: false)
            self.segmentedControl.scrollAndUpdateIndex(to: self.targetIndex)
        }
    }
}

1 Ответ

0 голосов
/ 02 апреля 2019

Перебрав множество ссылок на стек-потоки, я смог найти полезный ответ здесь и здесь . Моя проблема заключалась в том, что контроллер представления, находящийся в середине стека навигации, не будет пересчитывать свою компоновку до следующего прохода компоновки. Вы можете либо принудительно обновить макет, вызвав layoutIfNeeded() во время вращения, либо я переместил всю логику вращения в viewDidLayoutSubviews() и просто установил флаг в viewWillTransition:tosize, чтобы проверить, нужно ли выполнять логику вращения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...