What I am trying to do:
On Apple's Photo's App, if you rotate device while scroll to an arbitrary offset, same cell that was in the center beforehand would end up in the center after the rotation.
I am trying to achieve the same behavior with UICollectionView. 'indexPathsForVisibleItems' seem to be the way to do it....
What I got so far:
Following code provides smooth operation between rotates, yet the center item calculation seem to be off:
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
self.collectionView?.collectionViewLayout.invalidateLayout()
let middleItem = (self.collectionView?.indexPathsForVisibleItems.count / 2) - 1
let indexPath = self.collectionView?.indexPathsForVisibleItems[middleItem]
coordinator.animate(alongsideTransition: { ctx in
self.collectionView?.layoutIfNeeded()
self.collectionView?.scrollToItem(at: indexPath!, at: .centeredVertically, animated: false)
}, completion: { _ in
})
}
What Doesn't work with above code:
- Portrait -> Landscape: Somewhat off from what cell should end up in the center.
- Portrait -> Landscape -> Portrait: Completely off from what offset was in Portrait in the first place.
- Portrait -> Landscape -> Portrait -> Landscape: Way off!
Notes:
- I have to invalidate the collection view layout upon rotation due to cell sizes and spacing having to be recalculated.
- self.collectionView?.layoutIfNeeded() being inside the animation
block, make the transition smooth - May be scrollToItem is being called before the collection view layout is not finalized, leading to incorrect scroll offset?
Alternate Method?
Instead of using 'indexPathsForVisibleItems', use just 'contentOffset'? Calculate the offset after-rotation offset? But how would this be possible when after-rotation contentSize could be different than what's expected do to different cell sizes, cell spacing etc?
scrollToItem
. Maybe try putting that line in the completion block to see if you're actually targeting the right cell and position. If that works I think you'll have to do some clever calculations to animate thecontentOffset
instead of usingscrollToItem
. – AvarioscrollToItem
will position it, or whether it is a problem with the animation. – Avario