рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк SDK (UIKit Dynamics рдлреНрд░реЗрдорд╡рд░реНрдХ) рдХреЗ рдирд╡реАрдирддрдо рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рдЬрд╛рдирддреЗ рд╣реИрдВ, рдбреЗрд╡рд▓рдкрд░реНрд╕ UIView рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ рдХреЗ рд▓рд┐рдП рдбрд╛рдпрдирд╛рдорд┐рдХ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд╕рд╛рде рд╣реА рдЕрдиреНрдп рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ рдЬреЛ UID DynamicsicItem рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддреЗ рд╣реИрдВред
рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рдореИрдВ рдРрд╕реА рд╡рд╕реНрддреБрдУрдВ рдХреЗ рдЙрдкрдпреЛрдЧ рдХреЗ рдЕрдиреБрднрд╡ рдХреЛ рд╕рд╛рдЭрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред
рд▓рдХреНрд╖реНрдп рдЖрдИрдУрдПрд╕ 7 рдкрд░ рдореИрд╕реЗрдЬ рдРрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдХреЗ рд╕рдорд╛рди рдПрдХ рдПрдиреАрдореЗрд╢рди рдмрдирд╛рдирд╛ рдерд╛:

рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реАрдХрд░рдг рдХреА рдЦреЛрдЬ рдФрд░ рдЕрдзреНрдпрдпрди рдХреЗ рдмрд╛рдж,
UICynamicAnimator рдХрд╛ рдЙрдкрдпреЛрдЧ
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 рд╡рд░реНрдЧ рдХреЗ рдбрд╛рдпрдирд╛рдорд┐рдХ рдЖрдЗрдЯрдо рддрддреНрд╡ рдФрд░ рдЖрдЗрдЯрдо.рдХреЗрдВрдЯрд░ рдкреЙрдЗрдВрдЯ (рдЗрд╕ рддрддреНрд╡ рдХрд╛ рдХреЗрдВрджреНрд░) рдХреЗ рдмреАрдЪ рдХреЗ рд╕рдВрдмрдВрдз рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддрд╛ рд╣реИред рдЬрдм рдПрдХ рддрддреНрд╡ рдпрд╛ рдмрд┐рдВрджреБ рдЪрд▓рддрд╛ рд╣реИ, рддреЛ рд╕рдВрд▓рдЧреНрди рддрддреНрд╡ рднреА рдЧрддрд┐ рдХрд░рддрд╛ рд╣реИред рднрд┐рдЧреЛрдирд╛ рдФрд░ рдЖрд╡реГрддреНрддрд┐ рдЧреБрдгреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ, рд╣рдо рдпрд╣ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рд╕рдордп рдХреЗ рд╕рд╛рде рд╡реНрдпрд╡рд╣рд╛рд░ рдХреИрд╕реЗ рдмрджрд▓ рдЬрд╛рдПрдЧрд╛ред
рд╕реНрд░реЛрдд рдХреЛрдбIOS 7 рдореЗрдВ рдПрдирд┐рдореЗрд╢рди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЙрдкрдпреЛрдЧреА рд▓рд┐рдВрдХ: