I calculate itemSize dependent on safe area for UICollectionView with horizontal scroll and custom layout.
But for iPhone X safe area has different size for different orientation. My question is how should I calculate safe area size for landscape orientation in viewWillTransition function? Or how is it possible to do without this calculation?
EDIT
To get safe area size without creating any additional views, use this:
view.safeAreaLayoutGuide.layoutFrame.size
If you want to use viewWillTransition
method you can use this:
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
// Before rotation
print(view.safeAreaLayoutGuide.layoutFrame.size)
coordinator.animate(alongsideTransition: { (context) in
// During rotation
}) { (context) in
// After rotation
print(self.view.safeAreaLayoutGuide.layoutFrame.size)
}
}
In the completion block you will get your desired size, note however, that this code will be called after the rotation.
Original answer
Solution using additional UIView:
What I did was to create a UIView
and pin it with constant 0 to Safe Area Guides, so that it always matches size of Safe Area:
I created an @IBOutlet
of that UIView
and in viewDidLayoutSubviews()
check the size:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
print(containerView.frame.size)
}
After rotation I also get the updated size of that UIView.
Use UICollectionViewDelegateFlowLayout's collectionView(_:layout:sizeForItemAt:). Works like a charm.
Setting the size in the completion block of coordinator.animate(alongsideTransition:completion:) in viewWillTransition(to:with:) didn't work for me because the size animation occurs after the orientation animation ends, which looks weird.