我正在使用UICollectionView
创建一个全屏图像库。当用户旋转设备时,我会对
UICollectionView
执行更新
func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator)
我以模态方式呈现此UIViewController
并且UICollectionView
占据整个屏幕。在viewDidLoad
内,我将流布局创建为:
let flowLayout = UICollectionViewFlowLayout()
flowLayout.scrollDirection = .horizontal
flowLayout.minimumInteritemSpacing = 0
flowLayout.minimumLineSpacing = 0
photosCollectionView.isPagingEnabled = true
photosCollectionView.setCollectionViewLayout(flowLayout, animated: true)
我的大小也是:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return photosCollectionView.frame.size
}
当我旋转设备时,永远不会调用viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator)
,这会导致UICollectionViewLayout
不更新。当我旋转设备时,我收到消息:
The behavior of the UICollectionViewFlowLayout is not defined because: the item height must be less than the height of the UICollectionView minus the section insets top and bottom values, minus the content insets top and bottom values.
我在网上看到我可以添加:
self.automaticallyAdjustsScrollViewInsets = false
到UIViewController
,但没有任何影响。 UICollectionView
没有内容或部分插入内容。
我也在函数内调用super.viewWillTransition
。任何人都可以帮助我解决可能导致此问题的原因吗?
答案 0 :(得分:10)
如果您只关心设备旋转时的布局,请使用:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
collectionView.collectionViewLayout.invalidateLayout()
collectionView.layoutIfNeeded()
}
来自apple docs:
public func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator)
当视图控制器的视图大小为时,将调用此方法 由其父级更改(即,对于根视图控制器) 窗口旋转或调整大小)。 如果覆盖此方法,则应调用super将更改传播到子项或手动将更改转发到 孩子。
我猜你可以在不调用super
的情况下在该视图的父节点上调用此函数解决方法也是注册设备轮换:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
NotificationCenter.default.addObserver(self, selector: #selector(deviceOrientationDidChange), name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
NotificationCenter.default.removeObserver(self)
}
func deviceOrientationDidChange(_ notification: Notification) {
let orientation = UIDevice.current.orientation
print(orientation)
}
答案 1 :(得分:2)
我想重新发布我在另一个描述相同问题的thread中留下的答案。
人们已经解释过,您必须致电 super 。我想补充一条信息,可能会对那些会面对我的人有所帮助。
如果您的视图控制器是 child 视图控制器,则检查是否调用了 parent 视图控制器委托,以及是否在其中调用了 super 。否则它将不会传播到子视图控制器!
class ParentViewController: UIViewController {
func presentChild() {
let child = ChildViewController()
present(child, animated: false, compeltion: nil)
}
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator) // If this line is missing your child will not get the delegate call in it's viewWillTransition
// Do something
}
}
class ChildViewController: UIViewController {
// This method will not get called if presented from parent view controller and super is not called inside the viewViewWillTransition available there.
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
//Do something
}
}
P.S-这发生在我身上,因为我没有为父母写代码。
答案 2 :(得分:0)
这是我修复的方法:
转到项目目标 - 常规 - 部署信息
应用支持的勾选设备方向
您还需要(更改UIInterfaceOrientationMask.all
以获取适当的选项):
override var supportedInterfaceOrientations : UIInterfaceOrientationMask {
get {
return UIInterfaceOrientationMask.all;
}
}
用于ViewController。
答案 3 :(得分:0)
我替换了
func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator)
作者
func willTransition(to newCollection: UITraitCollection, with coordinator: UIViewControllerTransitionCoordinator)
它对我有用。