如何旋转类似于照片应用程序的UICollectionView并保持当前视图居中?

Shi*_*zam 11 cocoa-touch objective-c ios uicollectionview

我有一个照片库视图,使用a UICollectionView,a UICollectionViewFlowLayout,pagingEnabled水平滚动,一次只显示一个视图.

工作得很好,直到我试图旋转它...

当我旋转设备时,在willRotateToInterfaceOrientation:duration:我更新它collectionView.contentOffset所以它保持在正确的项目上,我调整currentCell的大小,以便它动画到新的尺寸. 问题出在两个状态之间的动画中,"前一个"方向从左上角开始动画,并在其他单元格中查看. 什么是我做错了,因为在屏幕上制作动画的视图是FUBAR?

这是它在行动中的样子:

http://www.smugmug.com/gallery/n-3F9kD/i-BwzRzRf/A(忽略不稳定的视频,那就是Quicktime的错:p)

这是我的willAnimateRotationToInterfaceOrientation:duration:

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
[super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];

// Update the flowLayout's size to the new orientation's size
UICollectionViewFlowLayout *flow = (UICollectionViewFlowLayout *)self.collectionView.collectionViewLayout;
if (UIInterfaceOrientationIsLandscape(toInterfaceOrientation)) {
    flow.itemSize = CGSizeMake(self.collectionView.frame.size.width, self.collectionView.frame.size.height);
} else {
    flow.itemSize = CGSizeMake(self.collectionView.frame.size.width, self.collectionView.frame.size.height);
}
self.collectionView.collectionViewLayout = flow;
[self.collectionView.collectionViewLayout invalidateLayout];

// Get the currently visible cell
PreviewCellView *currentCell = (PreviewCellView*)[self.collectionView cellForItemAtIndexPath:[NSIndexPath indexPathForRow:_currentIndex inSection:0]];

// Resize the currently index to the new flow's itemSize
CGRect frame = currentCell.frame;
frame.size = flow.itemSize;
currentCell.frame = frame;

// Keep the collection view centered by updating the content offset
CGPoint newContentOffset = CGPointMake(_currentIndex * frame.size.width, 0);
self.collectionView.contentOffset = newContentOffset;
}
Run Code Online (Sandbox Code Playgroud)

据我所知,我无法在任何地方找到任何示例代码,说明如何制作一个优雅旋转的"照片库"样式集合视图.

Goo*_*rel 5

我挣扎了很长一段时间,直到我至少找到了这个"整容解决方案":

在旋转期间,在collectionView的顶部添加带有当前图像(并设置正确的自动布局约束)的全屏UIImageView.像这样:

-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration: (NSTimeInterval)duration 
{

[self.collectionView.collectionViewLayout invalidateLayout];

    // show a UIImageView with the current image on top of the collectionView 
    // to cover the ugly animation
    self.imageViewOnTopOfCollectionView.image = [self imageForItemAtIndexPath:self.currentIndexPath];
    self.imageViewOnTopOfCollectionView.hidden = NO;

    // show a centered, very large 'fakeBackground' view on top of
    // the UICollectionView, but below the UIImageView
    self.fakeBackground.hidden = NO;
}

-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
    // ... set correct contentOffset

    // hide the fake views again
    self.imageViewOnTopOfCollectionView.hidden = YES;
    self.fakeBackground.hidden = YES;
}
Run Code Online (Sandbox Code Playgroud)

一个大的'fakeBackground'将是一个额外的改进,以防止部分丑陋的集合视图动画在旋转时在此imageViews框架外可见.例如,超大(大于所有维度中的视图边界)UIView具有与collectionView相同的背景颜色,z-Index恰好位于collectionView和imageView之间.