旋转后在UICollectionView中保留第一个可见项

时间:2014-10-14 01:51:39

标签: ios objective-c iphone uicollectionview

我在其他StackOverflow问题中搜索了答案,但我找不到以下问题的任何解决方案:

我正在尝试使用具有流布局(垂直)的UICollectionView,并使项目大小取决于屏幕大小(它应该利用iPad的宽度甚至横向的iPhone宽度)。 / p>

我想让UICollectionView在面向人像的iPhone上只显示一列项目,而在面向横向的iPhone上显示2列。当然,如果有更多水平房间可用,它也可以显示更多列,例如在iPad中。

为实现此行为,我执行了以下操作:

- (void)viewWillLayoutSubviews {

    [super viewWillLayoutSubviews];

    UICollectionViewFlowLayout *layout = (UICollectionViewFlowLayout *)self.collectionView.collectionViewLayout;
    NSInteger columns = 1 + ((NSInteger)(CGRectGetWidth(self.collectionView.frame) - layout.sectionInset.left - layout.sectionInset.right + layout.minimumInteritemSpacing)) / ((NSInteger)(layout.minimumInteritemSpacing + 300.0 + 1.0));
    layout.itemSize = CGSizeMake((CGRectGetWidth(self.collectionView.frame) - layout.sectionInset.left - layout.sectionInset.right - ((columns - 1) * layout.minimumInteritemSpacing)) / columns, layout.itemSize.height);

    [layout invalidateLayout];
 }

这非常好用,当我旋转手机时,我可以看到布局显示两列而不是一列。

但我无法让UICollectionView在旋转后保留第一个可见项目,因为它将内容偏移设置为旋转之前的内容。随着布局的改变,现在UICollectionView在横向上显示两列,这个新的内容偏移应该有一个新值,它对应于同一个项目,但是在新的布局下。

我尝试使用以下代码段,但我没有设法让它正常工作:

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

    NSIndexPath *firstAddShowCellIndexPath = [[[self.collectionView indexPathsForVisibleItems] sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
        NSIndexPath *ip1 = obj1;
        NSIndexPath *ip2 = obj2;
        return [ip1 compare:ip2];
    }] firstObject];

    if (firstAddShowCellIndexPath) {
        [self.collectionView scrollToItemAtIndexPath:firstAddShowCellIndexPath atScrollPosition:UICollectionViewScrollPositionTop animated:YES];
    }
}

我怀疑UICollectionView正在尝试在轮换期间处理内容偏移,所以我甚至尝试使用dispatch_afterwillRotateToInterfaceOrientation,但是虽然它确实有效,但它将内容偏移设置为延迟,之后旋转完成,给用户带来了非常糟糕的体验。

有什么想法吗?

谢谢大家!

1 个答案:

答案 0 :(得分:0)

这对我有用,

添加此代替willRotation方法

#pragma mark - Rotation
-(void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
    [self.collectionView.collectionViewLayout invalidateLayout];
}

举个例子,这是我在旋转之前和之后制作两个列的快速代码等。

#pragma mark <UICollectionViewDelegateFlowLayout>
- (CGSize)collectionView:(UICollectionView *)collectionView layout(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath*)indexPath
{
    int width = roundf(self.collectionView.frame.size.width / 2.0) - 15;
    int height = roundf(width * 0.8);
    return CGSizeMake(width, height);
}

- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section
{
    UIEdgeInsets new = UIEdgeInsetsMake(10, 10, 10, 10);
    return new;
}