Merge pull request #2886 from dreampiggy/feature_runloop_mac
Support the runloop mode control for macOS. Which can be useful when user want to pause animation when drag the mouse, or presenting modal window
This commit is contained in:
commit
387944bbc1
|
@ -81,13 +81,12 @@
|
|||
*/
|
||||
@property (nonatomic, assign) BOOL resetFrameIndexWhenStopped;
|
||||
|
||||
#if SD_UIKIT
|
||||
/**
|
||||
You can specify a runloop mode to let it rendering.
|
||||
Default is NSRunLoopCommonModes on multi-core iOS device, NSDefaultRunLoopMode on single-core iOS device
|
||||
Default is NSRunLoopCommonModes on multi-core device, NSDefaultRunLoopMode on single-core device
|
||||
@note This is useful for some cases, for example, always specify NSDefaultRunLoopMode, if you want to pause the animation when user scroll (for Mac user, drag the mouse or touchpad)
|
||||
*/
|
||||
@property (nonatomic, copy, nonnull) NSRunLoopMode runLoopMode;
|
||||
#endif
|
||||
@end
|
||||
|
||||
#endif
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
@interface SDAnimatedImageView () <CALayerDelegate> {
|
||||
BOOL _initFinished; // Extra flag to mark the `commonInit` is called
|
||||
NSRunLoopMode _runLoopMode;
|
||||
double _playbackRate;
|
||||
}
|
||||
|
||||
|
@ -149,6 +150,9 @@
|
|||
self.player.totalLoopCount = self.animationRepeatCount;
|
||||
}
|
||||
|
||||
// RunLoop Mode
|
||||
self.player.runLoopMode = self.runLoopMode;
|
||||
|
||||
// Play Rate
|
||||
self.player.playbackRate = self.playbackRate;
|
||||
|
||||
|
@ -188,12 +192,21 @@
|
|||
|
||||
- (void)setRunLoopMode:(NSRunLoopMode)runLoopMode
|
||||
{
|
||||
_runLoopMode = [runLoopMode copy];
|
||||
self.player.runLoopMode = runLoopMode;
|
||||
}
|
||||
|
||||
- (NSRunLoopMode)runLoopMode
|
||||
{
|
||||
return self.player.runLoopMode;
|
||||
if (!_runLoopMode) {
|
||||
_runLoopMode = [[self class] defaultRunLoopMode];
|
||||
}
|
||||
return _runLoopMode;
|
||||
}
|
||||
|
||||
+ (NSString *)defaultRunLoopMode {
|
||||
// Key off `activeProcessorCount` (as opposed to `processorCount`) since the system could shut down cores in certain situations.
|
||||
return [NSProcessInfo processInfo].activeProcessorCount > 1 ? NSRunLoopCommonModes : NSDefaultRunLoopMode;
|
||||
}
|
||||
|
||||
- (void)setPlaybackRate:(double)playbackRate
|
||||
|
|
|
@ -25,12 +25,13 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt
|
|||
#if SD_MAC
|
||||
@property (nonatomic, assign) CVDisplayLinkRef displayLink;
|
||||
@property (nonatomic, assign) CVTimeStamp outputTime;
|
||||
@property (nonatomic, copy) NSRunLoopMode runloopMode;
|
||||
#elif SD_IOS || SD_TV
|
||||
@property (nonatomic, strong) CADisplayLink *displayLink;
|
||||
#else
|
||||
@property (nonatomic, strong) NSTimer *displayLink;
|
||||
@property (nonatomic, strong) NSRunLoop *runloop;
|
||||
@property (nonatomic, strong) NSRunLoopMode runloopMode;
|
||||
@property (nonatomic, copy) NSRunLoopMode runloopMode;
|
||||
@property (nonatomic, assign) NSTimeInterval currentFireDate;
|
||||
#endif
|
||||
|
||||
|
@ -118,7 +119,7 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt
|
|||
return;
|
||||
}
|
||||
#if SD_MAC
|
||||
// CVDisplayLink does not use runloop
|
||||
self.runloopMode = mode;
|
||||
#elif SD_IOS || SD_TV
|
||||
[self.displayLink addToRunLoop:runloop forMode:mode];
|
||||
#else
|
||||
|
@ -141,7 +142,7 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt
|
|||
return;
|
||||
}
|
||||
#if SD_MAC
|
||||
// CVDisplayLink does not use runloop
|
||||
self.runloopMode = nil;
|
||||
#elif SD_IOS || SD_TV
|
||||
[self.displayLink removeFromRunLoop:runloop forMode:mode];
|
||||
#else
|
||||
|
@ -186,6 +187,14 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt
|
|||
}
|
||||
|
||||
- (void)displayLinkDidRefresh:(id)displayLink {
|
||||
#if SD_MAC
|
||||
// CVDisplayLink does not use runloop, but we can provide similar behavior for modes
|
||||
// May use `default` runloop to avoid extra callback when in `eventTracking` (mouse drag, scroll) or `modalPanel` (modal panel)
|
||||
NSString *runloopMode = self.runloopMode;
|
||||
if (![runloopMode isEqualToString:NSRunLoopCommonModes] && ![runloopMode isEqualToString:NSRunLoop.mainRunLoop.currentMode]) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
|
||||
[_target performSelector:_selector withObject:self];
|
||||
|
|
Loading…
Reference in New Issue