当设备方向发生变化时,UIViewController不会更新视图的约束

时间:2016-12-16 14:54:01

标签: ios swift autolayout orientation

我制作的应用可以在横向和纵向模式下使用iPad。 我的UIViewControllers的配置如下:

我有UIViewController UICollectionView,其中包含以下约束: top,leading,trailing和bottom 设置为 0 它的超级视图(超级视图是我UIView的{​​{1}}。

当我点击一个单元格时,我会在UIViewController中推送另一个UIViewController,这是该单元格的详细viewController。简单。

当我在第一个视图控制器中更改设备方向时,UINavigationController边界设置正确。

我的问题

如果我在UICollectionView中选择一个单元格,则会显示第二个详细信息viewController。然后,如果在第二个ViewController中我改变了设备方向,然后我回到第一个viewController,我的UICollectionView的视图还没有被旋转。我不知道为什么,我尝试了这个没有成功:

在我的firstViewController的UIViewController

self.view.layoutIfNeeded()根据当前方向更新约束,它没有工作。这没有用,因为我注意到了一件事:

我的第一个viewController的框架视图仍然与之前的方向相同,它没有改变......但是如果我再次旋转设备,viewDidAppear()检测到方向改变,并且视图边界设置正确。

所以我的问题是:当我在第二个视图控制器中,并且我正在旋转设备,然后我回到之前的视图控制器中时,前一个控制器没有' t检测到我刚在第二个视图控制器中进行的方向改变。

GIF演示:

enter image description here

之后我从纵向模式转为横向模式,视图 不会更改,因为调试视图层次结构工具显示如下:

enter image description here

UIViewController仍处于纵向状态,因此无法使用新方向更新UIView约束...

有什么想法吗?

2 个答案:

答案 0 :(得分:5)

通过使用viewWillAppear方法中的屏幕边界重置第一个viewController中的视图框架来解决:

public override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(true)
    self.view.frame = UIScreen.main.bounds
    self.view.layoutIfNeeded()
}

就像我的viewController的主要UIView有正确的框架,当我在我的UIView上调用layoutIfNeeded()时,约束可以自动更新。

答案 1 :(得分:0)

发现需要重置collectionview的帧大小。添加self.collectionview.frame.size = size

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {

    if let layout = self.collectionview.collectionViewLayout as? UICollectionViewFlowLayout {
        let width = (size.width - 30) / 3
        layout.itemSize = CGSize(width:width, height:width)
        self.collectionview.frame.size = size
        layout.invalidateLayout()
    }
}