-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathVVSpringCollectionViewFlowLayout.m
More file actions
executable file
·93 lines (75 loc) · 3.07 KB
/
Copy pathVVSpringCollectionViewFlowLayout.m
File metadata and controls
executable file
·93 lines (75 loc) · 3.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
//
// VVSpringCollectionViewFlowLayout.m
// VVSpringCollectionViewDemo
//
// Created by 王 巍 on 13-9-1.
// Copyright (c) 2013年 王 巍. All rights reserved.
//
#import "VVSpringCollectionViewFlowLayout.h"
@interface VVSpringCollectionViewFlowLayout()
@property (nonatomic, strong) UIDynamicAnimator *animator;
@end
@implementation VVSpringCollectionViewFlowLayout
-(id)init {
if ([super init]) {
_springDamping = 0.5;
_springFrequency = 0.8;
_resistanceFactor = 500;
}
return self;
}
-(void)setSpringDamping:(CGFloat)springDamping {
if (springDamping >= 0 && _springDamping != springDamping) {
_springDamping = springDamping;
for (UIAttachmentBehavior *spring in _animator.behaviors) {
spring.damping = _springDamping;
}
}
}
-(void)setSpringFrequency:(CGFloat)springFrequency {
if (springFrequency >= 0 && _springFrequency != springFrequency) {
_springFrequency = springFrequency;
for (UIAttachmentBehavior *spring in _animator.behaviors) {
spring.frequency = _springFrequency;
}
}
}
-(void)prepareLayout {
[super prepareLayout];
if (!_animator) {
_animator = [[UIDynamicAnimator alloc] initWithCollectionViewLayout:self];
CGSize contentSize = [self collectionViewContentSize];
NSArray *items = [super layoutAttributesForElementsInRect:CGRectMake(0, 0, contentSize.width, contentSize.height)];
for (UICollectionViewLayoutAttributes *item in items) {
UIAttachmentBehavior *spring = [[UIAttachmentBehavior alloc] initWithItem:item attachedToAnchor:item.center];
spring.length = 0;
spring.damping = self.springDamping;
spring.frequency = self.springFrequency;
[_animator addBehavior:spring];
}
}
}
-(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect {
return [_animator itemsInRect:rect];
}
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath {
return [_animator layoutAttributesForCellAtIndexPath:indexPath];
}
-(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds {
UIScrollView *scrollView = self.collectionView;
CGFloat scrollDelta = newBounds.origin.y - scrollView.bounds.origin.y;
CGPoint touchLocation = [scrollView.panGestureRecognizer locationInView:scrollView];
for (UIAttachmentBehavior *spring in _animator.behaviors) {
CGPoint anchorPoint = spring.anchorPoint;
CGFloat distanceFromTouch = fabsf(touchLocation.y - anchorPoint.y);
CGFloat scrollResistance = distanceFromTouch / self.resistanceFactor;
UICollectionViewLayoutAttributes *item = [spring.items firstObject];
CGPoint center = item.center;
center.y += (scrollDelta > 0) ? MIN(scrollDelta, scrollDelta * scrollResistance)
: MAX(scrollDelta, scrollDelta * scrollResistance);
item.center = center;
[_animator updateItemUsingCurrentState:item];
}
return NO;
}
@end