【问题标题】:UICollectionView rearrange cells on rotationUICollectionView 在旋转时重新排列单元格
【发布时间】:2013-04-29 13:49:21
【问题描述】:

我想在我的设备旋转期间重新排列UICollectionView 单元格,这与在注释的evernote iPads app 中完成的方式类似。在默认实现中,只有单元格的淡入和淡出,但我希望单元格在旋转期间四处移动。

实现类似动画的推荐方法是什么?我需要创建自定义UICollectionViewLayout吗?

【问题讨论】:

    标签: ios6 uicollectionview evernote uicollectionviewlayout


    【解决方案1】:

    我设法通过继承UICollectionViewFlowLayout 并覆盖两个方法来获得所需的旋转效果:initialLayoutAttributesForAppearingItemAtIndexPathfinalLayoutAttributesForDisappearingItemAtIndexPath 这两个控制点分别定义要插入的项目的开始/最终布局信息进入集合视图。

    查看源代码:

    .h:

    #import "UICollectionView.h"
    
    @interface UITestCollectionViewFlowLayout : UICollectionViewFlowLayout
    @end
    

    .m:

    #import "UITestCollectionViewFlowLayout.h"
    
    @interface UITestCollectionViewFlowLayout () 
    {
        BOOL _isRotating; 
    }
    
    @property (strong, nonatomic) NSIndexPath* lastDissappearingItemIndex;
    
    @end
    
    @implementation UITestCollectionViewFlowLayout
    
    @synthesize lastDissappearingItemIndex = _lastDissappearingItemIndex;
    
    // returns the starting layout information for an item being inserted into the collection view
    - (UICollectionViewLayoutAttributes *)initialLayoutAttributesForAppearingItemAtIndexPath:(NSIndexPath *)itemIndexPath
    {
    
        UICollectionViewLayoutAttributes* attributes = (UICollectionViewLayoutAttributes *)[self layoutAttributesForItemAtIndexPath:itemIndexPath];
    
        if (_isRotating) // we want to customize the cells layout only during the rotation event
        {
            if ([self.lastDissappearingItemIndex isEqual:itemIndexPath])
                return nil; // do not animate appearing cell for the one that just dissapear
            else
            {
                attributes.alpha = 0;
    
                // setting the alpha to the new cells that didn't match the ones dissapearing is not enough to not see them so we offset them
                attributes.center =  CGPointMake(attributes.center.x, attributes.size.height * 2 + attributes.center.y);
            }
    
        }
    
        return attributes;
    }
    
    // returns the final layout information for an item that is about to be removed from the collection view
    - (UICollectionViewLayoutAttributes *)finalLayoutAttributesForDisappearingItemAtIndexPath:(NSIndexPath*)itemIndexPath
    {
    
        UICollectionViewLayoutAttributes* attributes = (UICollectionViewLayoutAttributes *)[self layoutAttributesForItemAtIndexPath:itemIndexPath];
    
        if (_isRotating)
        {
            attributes.alpha = 1.0;
    
            self.lastDissappearingItemIndex = itemIndexPath;
        }
    
        return attributes;
    }
    
    - (void) viewController:(UIViewController *)viewController didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
    {
        _isRotating = NO;
    }
    
    - (void) viewController:(UIViewController *)viewController willRotateToInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation duration:(NSTimeInterval)duration
    {
        _isRotating = YES;
    }
    

    请注意,我正在使用从创建此流程布局的视图控制器设置的标志来了解我们何时实际旋转;原因是我希望这种效果只在旋转期间发生。

    我很想听听有关此代码的反馈/改进。

    【讨论】:

    • 太棒了!完美运行。