如何旋转UICollectionView类似于照片应用程序,并保持当前视图居中? [英] How to rotate a UICollectionView similar to the photos app and keep the current view centered?

查看:142
本文介绍了如何旋转UICollectionView类似于照片应用程序,并保持当前视图居中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个照片库视图,使用 UICollectionView UICollectionViewFlowLayout ,它有 pagingEnabled 并且水平滚动,每次只显示一个视图。



效果很好,直到我尝试旋转...



当我旋转设备时,在 willRotateToInterfaceOrientation:duration:我更新 collectionView.contentOffset 所以它保持在正确的项目,我调整currentCell的大小,所以它动画到新的维度。 问题出在动画中的两个状态之间,上一个方向动画从左上角 并跳入视图其他单元格。是什么



这是它在行动中的样子:



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];

//将flowLayout的大小更新为新方向的大小
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];

//获取当前可见的单元格
PreviewCellView * currentCell =(PreviewCellView *)[self.collectionView cellForItemAtIndexPath:[NSIndexPath indexPathForRow:_currentIndex inSection:0]];

//调整当前索引到新流的itemSize
CGRect frame = currentCell.frame;
frame.size = flow.itemSize;
currentCell.frame = frame;

//通过更新内容偏移保持集合视图居中
CGPoint newContentOffset = CGPointMake(_currentIndex * frame.size.width,0);
self.collectionView.contentOffset = newContentOffset;
}

据我所知,我找不到任何示例代码

解决方案

我在这个问题上挣扎了很长一段时间,直到我至少找到这个美容解决方法:



添加一个全屏UIImageView与当前图像(和正确的自动布局约束设置)回转。像这样:

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

[self.collectionView.collectionViewLayout invalidateLayout];

//显示一个UIImageView与当前图像在collectionView
//覆盖丑陋的动画
self.imageViewOnTopOfCollectionView.image = [self imageForItemAtIndexPath:self.currentIndexPath ];
self.imageViewOnTopOfCollectionView.hidden = NO;

//在
上面显示一个居中,非常大的'fakeBackground'视图// UICollectionView,但低于UIImageView
self.fakeBackground.hidden = NO;
}

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
// ...设置正确contentOffset

再次隐藏假视图
self.imageViewOnTopOfCollectionView.hidden = YES;
self.fakeBackground.hidden = YES;
}

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


I have a photo gallery view that uses a UICollectionView with a UICollectionViewFlowLayout, it has pagingEnabled and scrolls horizontally showing only one view at a time.

Works great till I try to rotate it...

When I rotate the device, in willRotateToInterfaceOrientation:duration: I update the collectionView.contentOffset so it stays on the correct item and I resize the currentCell so it animates into the new dimensions. The problem is in the animation between the two states, the 'previous' orientation animates from the upper left corner AND flings into the view other cells. What is it I'm doing wrong such that the view being animated off the screen is FUBAR?

Here is what it looks like in action:

http://www.smugmug.com/gallery/n-3F9kD/i-BwzRzRf/A (ignore the choppy video, thats Quicktime's fault :p)

Here is my 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;
}

As far as I'm aware I can't find any sample code anywhere that illustrates how to make a 'photo gallery' style collection view that rotates gracefully.

解决方案

I struggled with this for quite a while, until I at least found this 'cosmetic workaround':

Add a full screen UIImageView with the current image (and correct auto layout constraints set) on top of the collectionView during rotation. Like so:

-(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;
}

A large 'fakeBackground' would be an extra improvement to prevent parts of the ugly collection view animation being visible outside this imageViews frame while it rotates. E.g. an oversized (larger than the view's bounds in all dimensions) UIView with the same background color as the collectionView, with a z-Index just between the collectionView and the imageView.

这篇关于如何旋转UICollectionView类似于照片应用程序,并保持当前视图居中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆