Reputation: 1027
I have a UICollectionView
with paging enabled, the page contentOffset
is not correctly adjusted after rotation.
I overrided the two following methods
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
collectionView.collectionViewLayout.invalidateLayout()
}
override func didRotateFromInterfaceOrientation(fromInterfaceOrientation: UIInterfaceOrientation) {
let width = collectionView.bounds.width
var frame = collectionView.frame
frame.origin.x = width * CGFloat(pageControl.currentPage)
frame.origin.y = 0
collectionView.scrollRectToVisible(frame, animated: false)
}
but still have the same problem.
What needs to be done for these changes to adjust contentOffset of the current page correctly when the device is rotated?
on landscape the page is positioned correctly , but when the device is rotated to portrait the page position is incorrect as in the following images
Upvotes: 1
Views: 2560
Reputation: 71
I've fixed this problem with the next code:
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
CGPoint offset = self.collectionView.contentOffset;
CGFloat width = self.collectionView.bounds.size.width;
NSInteger index = round(offset.x / width);
CGPoint newOffset = CGPointMake(index * size.width, offset.y);
[self.collectionView setContentOffset:newOffset animated:NO];
[coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
[self.collectionView reloadData];
[self.collectionView setContentOffset:newOffset animated:NO];
} completion:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
}];
}
But take into account that my photos is scrolled horizontally.
Animation during this transition is not very smooth, but acceptable. If you want to make it excellent you can hide a collectionView before a rotation and place an image view with current image on the screen. Image view should rotate without any problem. After rotation you can run an appropriate code from above and after that remove an image view from the screen. I have not tried to implement this idea yet, but it should look like:
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
CGPoint offset = self.collectionView.contentOffset;
CGFloat width = self.collectionView.bounds.size.width;
NSInteger index = round(offset.x / width);
CGPoint newOffset = CGPointMake(index * size.width, offset.y);
//here you should create an image view and place it on the screen
//without animation, you should also make constraints for it
//you also should hide the collection view
[coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
} completion:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
[self.collectionView reloadData];
[self.collectionView setContentOffset:newOffset animated:NO];
//here you should remove the image view and show the collection view
}];
}
Sorry for Objective C :).
Upvotes: 3