Skip to content

Commit c1f60d2

Browse files
committed
Merge pull request lxcid#30 from zadr/master
Use CADisplayLink instead of NSTimer, dataSource updates
2 parents d5bfb4d + 1642a72 commit c1f60d2

File tree

3 files changed

+46
-20
lines changed

3 files changed

+46
-20
lines changed

LXRCVFL Example using Storyboard/LXRCVFL Example using Storyboard.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
objects = {
88

99
/* Begin PBXBuildFile section */
10+
927A97F41736CA0E00539F5E /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 927A97F31736CA0E00539F5E /* QuartzCore.framework */; };
1011
AB0E97C7161B4BEC005498A0 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB0E97C6161B4BEC005498A0 /* UIKit.framework */; };
1112
AB0E97C9161B4BEC005498A0 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB0E97C8161B4BEC005498A0 /* Foundation.framework */; };
1213
AB0E97CB161B4BEC005498A0 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB0E97CA161B4BEC005498A0 /* CoreGraphics.framework */; };
@@ -25,6 +26,7 @@
2526
/* End PBXBuildFile section */
2627

2728
/* Begin PBXFileReference section */
29+
927A97F31736CA0E00539F5E /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
2830
AB0E97C2161B4BEC005498A0 /* LXRCVFL Example using Storyboard.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "LXRCVFL Example using Storyboard.app"; sourceTree = BUILT_PRODUCTS_DIR; };
2931
AB0E97C6161B4BEC005498A0 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
3032
AB0E97C8161B4BEC005498A0 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
@@ -55,6 +57,7 @@
5557
isa = PBXFrameworksBuildPhase;
5658
buildActionMask = 2147483647;
5759
files = (
60+
927A97F41736CA0E00539F5E /* QuartzCore.framework in Frameworks */,
5861
AB0E97C7161B4BEC005498A0 /* UIKit.framework in Frameworks */,
5962
AB0E97C9161B4BEC005498A0 /* Foundation.framework in Frameworks */,
6063
AB0E97CB161B4BEC005498A0 /* CoreGraphics.framework in Frameworks */,
@@ -86,6 +89,7 @@
8689
AB0E97C5161B4BEC005498A0 /* Frameworks */ = {
8790
isa = PBXGroup;
8891
children = (
92+
927A97F31736CA0E00539F5E /* QuartzCore.framework */,
8993
AB0E97C6161B4BEC005498A0 /* UIKit.framework */,
9094
AB0E97C8161B4BEC005498A0 /* Foundation.framework */,
9195
AB0E97CA161B4BEC005498A0 /* CoreGraphics.framework */,

LXReorderableCollectionViewFlowLayout/LXReorderableCollectionViewFlowLayout.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,11 @@
2020

2121
@protocol LXReorderableCollectionViewDataSource <UICollectionViewDataSource>
2222

23-
- (void)collectionView:(UICollectionView *)collectionView itemAtIndexPath:(NSIndexPath *)fromIndexPath willMoveToIndexPath:(NSIndexPath *)toIndexPath;
24-
2523
@optional
2624

25+
- (void)collectionView:(UICollectionView *)collectionView itemAtIndexPath:(NSIndexPath *)fromIndexPath willMoveToIndexPath:(NSIndexPath *)toIndexPath;
26+
- (void)collectionView:(UICollectionView *)collectionView itemAtIndexPath:(NSIndexPath *)fromIndexPath didMoveToIndexPath:(NSIndexPath *)toIndexPath;
27+
2728
- (BOOL)collectionView:(UICollectionView *)collectionView canMoveItemAtIndexPath:(NSIndexPath *)indexPath;
2829
- (BOOL)collectionView:(UICollectionView *)collectionView itemAtIndexPath:(NSIndexPath *)fromIndexPath canMoveToIndexPath:(NSIndexPath *)toIndexPath;
2930

LXReorderableCollectionViewFlowLayout/LXReorderableCollectionViewFlowLayout.m

Lines changed: 39 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#import "LXReorderableCollectionViewFlowLayout.h"
99
#import <QuartzCore/QuartzCore.h>
10+
#import <objc/runtime.h>
1011

1112
#define LX_FRAMES_PER_SECOND 60.0
1213

@@ -28,6 +29,20 @@ typedef NS_ENUM(NSInteger, LXScrollingDirection) {
2829
static NSString * const kLXScrollingDirectionKey = @"LXScrollingDirection";
2930
static NSString * const kLXCollectionViewKeyPath = @"collectionView";
3031

32+
@interface CADisplayLink (LX_userInfo)
33+
@property (nonatomic, copy) NSDictionary *LX_userInfo;
34+
@end
35+
36+
@implementation CADisplayLink (LX_userInfo)
37+
- (void) setLX_userInfo:(NSDictionary *) LX_userInfo {
38+
objc_setAssociatedObject(self, "LX_userInfo", LX_userInfo, OBJC_ASSOCIATION_COPY);
39+
}
40+
41+
- (NSDictionary *) LX_userInfo {
42+
return objc_getAssociatedObject(self, "LX_userInfo");
43+
}
44+
@end
45+
3146
@interface UICollectionViewCell (LXReorderableCollectionViewFlowLayout)
3247

3348
- (UIImage *)LX_rasterizedImage;
@@ -52,7 +67,7 @@ @interface LXReorderableCollectionViewFlowLayout ()
5267
@property (strong, nonatomic) UIView *currentView;
5368
@property (assign, nonatomic) CGPoint currentViewCenter;
5469
@property (assign, nonatomic) CGPoint panTranslationInCollectionView;
55-
@property (strong, nonatomic) NSTimer *scrollingTimer;
70+
@property (strong, nonatomic) CADisplayLink *displayLink;
5671

5772
@property (assign, nonatomic, readonly) id<LXReorderableCollectionViewDataSource> dataSource;
5873
@property (assign, nonatomic, readonly) id<LXReorderableCollectionViewDelegateFlowLayout> delegate;
@@ -139,48 +154,54 @@ - (void)invalidateLayoutIfNecessary {
139154

140155
self.selectedItemIndexPath = newIndexPath;
141156

142-
[self.dataSource collectionView:self.collectionView itemAtIndexPath:previousIndexPath willMoveToIndexPath:newIndexPath];
143-
157+
if ([self.dataSource respondsToSelector:@selector(collectionView:itemAtIndexPath:willMoveToIndexPath:)]) {
158+
[self.dataSource collectionView:self.collectionView itemAtIndexPath:previousIndexPath willMoveToIndexPath:newIndexPath];
159+
}
160+
144161
__weak typeof(self) weakSelf = self;
145162
[self.collectionView performBatchUpdates:^{
146163
__strong typeof(self) strongSelf = weakSelf;
147164
if (strongSelf) {
148165
[strongSelf.collectionView deleteItemsAtIndexPaths:@[ previousIndexPath ]];
149166
[strongSelf.collectionView insertItemsAtIndexPaths:@[ newIndexPath ]];
150167
}
151-
} completion:nil];
168+
} completion:^(BOOL finished) {
169+
__strong typeof(self) strongSelf = weakSelf;
170+
if ([strongSelf.dataSource respondsToSelector:@selector(collectionView:itemAtIndexPath:didMoveToIndexPath:)]) {
171+
[strongSelf.dataSource collectionView:strongSelf.collectionView itemAtIndexPath:previousIndexPath didMoveToIndexPath:newIndexPath];
172+
}
173+
}];
152174
}
153175

154176
- (void)invalidatesScrollTimer {
155-
if (self.scrollingTimer.isValid) {
156-
[self.scrollingTimer invalidate];
177+
if (!self.displayLink.paused) {
178+
[self.displayLink invalidate];
157179
}
158-
self.scrollingTimer = nil;
180+
self.displayLink = nil;
159181
}
160182

161183
- (void)setupScrollTimerInDirection:(LXScrollingDirection)direction {
162-
if (self.scrollingTimer.isValid) {
163-
LXScrollingDirection oldDirection = [self.scrollingTimer.userInfo[kLXScrollingDirectionKey] integerValue];
164-
184+
if (!self.displayLink.paused) {
185+
LXScrollingDirection oldDirection = [self.displayLink.LX_userInfo[kLXScrollingDirectionKey] integerValue];
186+
165187
if (direction == oldDirection) {
166188
return;
167189
}
168190
}
169191

170192
[self invalidatesScrollTimer];
171-
172-
self.scrollingTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 / LX_FRAMES_PER_SECOND
173-
target:self
174-
selector:@selector(handleScroll:)
175-
userInfo:@{ kLXScrollingDirectionKey : @(direction) }
176-
repeats:YES];
193+
194+
self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(handleScroll:)];
195+
self.displayLink.LX_userInfo = @{ kLXScrollingDirectionKey : @(direction) };
196+
197+
[self.displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
177198
}
178199

179200
#pragma mark - Target/Action methods
180201

181202
// Tight loop, allocate memory sparely, even if they are stack allocation.
182-
- (void)handleScroll:(NSTimer *)timer {
183-
LXScrollingDirection direction = (LXScrollingDirection)[timer.userInfo[kLXScrollingDirectionKey] integerValue];
203+
- (void)handleScroll:(CADisplayLink *)displayLink {
204+
LXScrollingDirection direction = (LXScrollingDirection)[displayLink.LX_userInfo[kLXScrollingDirectionKey] integerValue];
184205
if (direction == LXScrollingDirectionUnknown) {
185206
return;
186207
}

0 commit comments

Comments
 (0)