Главная
Блог разработчиков phpBB
 
+ 17 предустановленных модов
+ SEO-оптимизация форума
+ авторизация через соц. сети
+ защита от спама

Применение UIDynamicAnimator из UIKit Dynamics при создании таблиц на основе UICollectionView

Anna | 2.07.2014 | нет комментариев

Как вестимо в последней версии SDK (фреймворк UIKit Dynamics) разработчики могут определять динамическое поведение для UIView объектов, а также других объектов, принимающих протокол UIDynamicItem.

В данной статье я хочу поделиться навыком применения таких объектов.

Целью было сделать анимацию, аналогичную той, что применяется в приложении Messages на iOS 7:

image

Позже поисков и постижения документации решено было применять UIDynamicAnimator в связке сUICollectionView.

Для этого нужно было сделать класс-преемник UICollectionViewFlowLayout:

#import <UIKit/UIKit.h>

@interface DVCollectionViewFlowLayout : UICollectionViewFlowLayout

@end

добавить качество с типом UIDynamicAnimator


#import "DVCollectionViewFlowLayout.h"

@interface DVCollectionViewFlowLayout()

//объект-аниматор
@property (nonatomic, strong) UIDynamicAnimator *dynamicAnimator;

@end

@implementation DVCollectionViewFlowLayout

@synthesize dynamicAnimator = _dynamicAnimator;

-(id)initr{
    self = [super init];
    if (self){
        _dynamicAnimator = [[UIDynamicAnimator alloc] initWithCollectionViewLayout:self];
    }
    return self;
}

Динамическое поведение становится энергичным, когда мы его добавляем к объекту, тот, что является экземпляром UIDynamicAnimator. Аниматор определяет контекст, в котором динамическое поведение выполняется.

Позже этого мы обязаны переопределить в нём нижеперечисленные функции:


#import "DVCollectionViewFlowLayout.h"

 // .........

- (void)prepareLayout{

    [super prepareLayout];

    CGSize contentSize = [self collectionViewContentSize];
    NSArray *items = [super layoutAttributesForElementsInRect:CGRectMake(0, 0, contentSize.width, contentSize.height)];

    if (items.count != self.dynamicAnimator.behaviors.count) {
        [self.dynamicAnimator removeAllBehaviors];

        for (UICollectionViewLayoutAttributes *item in items) {
            UIAttachmentBehavior *springBehavior = [[UIAttachmentBehavior alloc] initWithItem:item attachedToAnchor:item.center];
//экспериментальным путём подобранные значения для лучшего воспринятия (на глаз)
            springBehavior.length = 0.f;
            springBehavior.damping = 1.f;
            springBehavior.frequency = 6.8f;

            [self.dynamicAnimator addBehavior:springBehavior];
        }
    }
}

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect{
    return [self.dynamicAnimator itemsInRect:rect];
}

- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath{
    return [self.dynamicAnimator layoutAttributesForCellAtIndexPath:indexPath];
}

- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds{
    CGFloat scrollDelta = newBounds.origin.y - self.collectionView.bounds.origin.y;
    CGPoint touchLocation = [self.collectionView.panGestureRecognizer locationInView:self.collectionView];

    for (UIAttachmentBehavior *springBehavior in self.dynamicAnimator.behaviors) {
        CGPoint anchorPoint = springBehavior.anchorPoint;
        CGFloat touchDistance = fabsf(touchLocation.y - anchorPoint.y);
       //экспериментальным путём подобранные значения для лучшего воспринятия (на глаз)
 CGFloat resistanceFactor = 0.002;

        UICollectionViewLayoutAttributes *attributes = springBehavior.items.firstObject;

        CGPoint center = attributes.center;

        float resistedScroll = scrollDelta * touchDistance * resistanceFactor;
        float simpleScroll = scrollDelta;

        float actualScroll = MIN(abs(simpleScroll), abs(resistedScroll));
        if(simpleScroll < 0){
            actualScroll *= -1;
        }

        center.y  = actualScroll;
        attributes.center = center;

        [self.dynamicAnimator updateItemUsingCurrentState:attributes];
    }

    return NO;
}

-(void)dealloc{
        [self.dynamicAnimator removeAllBehaviors];
        self.dynamicAnimator = nil;
}

Объект UIAttachmentBehavior определяет связь между динамическим элементом item класса UICollectionViewLayoutAttributes и точкой item.center (центром этого элемента). Когда один элемент либо точка перемещается, присоединенный элемент также перемещается. C поддержкой свойств damping и frequency мы можем указать как изменится поведение с течением времени.

Начальный код

Пригодные ссылки про анимации в iOS 7:

Источник: programmingmaster.ru

Оставить комментарий
Форум phpBB, русская поддержка форума phpBB
Рейтинг@Mail.ru 2008 - 2017 © BB3x.ru - русская поддержка форума phpBB