Skip to content

Commit 96571cb

Browse files
author
Zach Drayer
committed
Use CADisplayLink instead of NSTimer to know when to redraw on scroll.
1 parent d5bfb4d commit 96571cb

File tree

2 files changed

+33
-15
lines changed

2 files changed

+33
-15
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.m

Lines changed: 29 additions & 15 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;
@@ -152,35 +167,34 @@ - (void)invalidateLayoutIfNecessary {
152167
}
153168

154169
- (void)invalidatesScrollTimer {
155-
if (self.scrollingTimer.isValid) {
156-
[self.scrollingTimer invalidate];
170+
if (!self.displayLink.paused) {
171+
[self.displayLink invalidate];
157172
}
158-
self.scrollingTimer = nil;
173+
self.displayLink = nil;
159174
}
160175

161176
- (void)setupScrollTimerInDirection:(LXScrollingDirection)direction {
162-
if (self.scrollingTimer.isValid) {
163-
LXScrollingDirection oldDirection = [self.scrollingTimer.userInfo[kLXScrollingDirectionKey] integerValue];
164-
177+
if (!self.displayLink.paused) {
178+
LXScrollingDirection oldDirection = [self.displayLink.LX_userInfo[kLXScrollingDirectionKey] integerValue];
179+
165180
if (direction == oldDirection) {
166181
return;
167182
}
168183
}
169184

170185
[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];
186+
187+
self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(handleScroll:)];
188+
self.displayLink.LX_userInfo = @{ kLXScrollingDirectionKey : @(direction) };
189+
190+
[self.displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
177191
}
178192

179193
#pragma mark - Target/Action methods
180194

181195
// Tight loop, allocate memory sparely, even if they are stack allocation.
182-
- (void)handleScroll:(NSTimer *)timer {
183-
LXScrollingDirection direction = (LXScrollingDirection)[timer.userInfo[kLXScrollingDirectionKey] integerValue];
196+
- (void)handleScroll:(CADisplayLink *)displayLink {
197+
LXScrollingDirection direction = (LXScrollingDirection)[displayLink.LX_userInfo[kLXScrollingDirectionKey] integerValue];
184198
if (direction == LXScrollingDirectionUnknown) {
185199
return;
186200
}

0 commit comments

Comments
 (0)