2013-04-29 2 views
1

Я хотел бы переставить UICollectionView ячейки во время вращения устройства таким же образом, как это делается в evernote iPads app для заметок. В реализации по умолчанию есть только постепенное исчезновение и исчезновение ячеек, но я хотел бы, чтобы ячейки перемещались во время вращения.UICollectionView переупорядочивает ячейки при вращении

Каким будет рекомендуемый способ достижения подобной анимации? Нужно ли создавать пользовательские UICollectionViewLayout?

ответ

1

мне удалось получить желаемый эффект вращения с помощью подклассов UICollectionViewFlowLayout и опрокинув два метода: initialLayoutAttributesForAppearingItemAtIndexPath и finalLayoutAttributesForDisappearingItemAtIndexPath которые являются две точками управления, чтобы соответственно определить/окончательную информацию компоновки начальной для элемента вставляются в поле зрения сбора.

См Исходный код:

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

Обратите внимание, что я использую флаг, который я набор из ViewController кто создайте этот поток, чтобы знать, когда мы на самом деле вращаемся или нет; причина в том, что я хочу, чтобы этот эффект произошел только во время вращения.

Мне интересно услышать отзывы/улучшения об этом коде.

+1

Awesomesause! Работает отлично. –

+0

Прохладный - всегда приятно слышать, что это помогает кому-то :-) – tiguero