iOS:更改方向后弹出视图控制器时,约束会中断

时间:2019-03-28 17:41:56

标签: ios swift uicollectionview navigation autolayout

您的学生在这里学得很快。在iPad上,我一直在构建一个自定义的分段控件应用程序,在纵向中,分段控件位于顶部,而在横向中,分段控件位于左侧。通过将collectionView嵌入UIView中来实现分段控件。这只是帮助我将数据源/委托方法与viewController分开。内容由标准的嵌套collectionView显示。像这样:

portrait enter image description here

我已设法在此视图控制器内处理旋转,而没有任何警告或错误。我启动了两个纵向和横向约束数组,并根据需要在viewWillTransitionToSize中停用/激活了它们。在以下情况下会发生此问题: 将新视图控制器推到该控制器上->旋转设备->弹出该控制器

在新的视图控制器上旋转到纵向并弹出会导致“ 未定义UICollectionViewFLowLayout ”错误。旋转到横向的程度较轻,这会导致内容收集视图的大小错误。像这样:

Portrait bug Landscape 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 :(得分:0)

在跳过了很多stackoverflow链接之后,我能够找到一个有用的答案herehere。我的问题是,位于导航堆栈中间的视图控制器在下一次布局通过之前不会重新计算其布局。您可以通过在旋转过程中调用layoutIfNeeded()来强制进行布局更新,或者我将所有旋转逻辑都移动到了viewDidLayoutSubviews()并只是在viewWillTransition:tosize中设置了一个标志来检查是否需要执行您的旋转逻辑。