UICollectionViewに基づいてテーブルを作成するときにUIKit DynamicsからUIDynamicAnimatorを使用

SDKの最新バージョン(UIKit Dynamicsフレームワーク)で知っているように、開発者はUIViewオブジェクトや、UIDynamicItemプロトコルを受け入れる他のオブジェクトの動的な動作を定義できます。



この記事では、そのようなオブジェクトを使用した経験を共有したいと思います。



目標は、iOS 7のメッセージアプリで使用されているアニメーションに似たアニメーションを作成することでした。



画像



ドキュメントを検索して調査した後、 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オブジェクトは、UICollectionViewLayoutAttributesクラスの動的アイテムアイテムとitem.centerポイント(このアイテムの中心)の関係を定義します。 1つの要素またはポイントが移動すると、アタッチされた要素も移動します。 減衰と周波数のプロパティを使用して、動作が時間とともにどのように変化するかを指定できます。



ソースコード



iOS 7のアニメーションに関する便利なリンク:








All Articles