diff --git a/Source/Classes/AnimatedImages/PINAnimatedImageView.m b/Source/Classes/AnimatedImages/PINAnimatedImageView.m index 97ae06f0..cf7f3e79 100644 --- a/Source/Classes/AnimatedImages/PINAnimatedImageView.m +++ b/Source/Classes/AnimatedImages/PINAnimatedImageView.m @@ -23,8 +23,6 @@ @interface PINAnimatedImageView () @property (nonatomic, assign) CGImageRef frameImage; @property (nonatomic, strong) PINDisplayLink *displayLink; -@property (nonatomic, assign) CFTimeInterval lastDisplayLinkFire; - @end @implementation PINAnimatedImageView @@ -239,7 +237,6 @@ - (void)stopAnimating PINAssertMain(); _displayLink.paused = YES; - _lastDisplayLinkFire = 0; [_animatedImage clearAnimatedImageCache]; } @@ -352,14 +349,11 @@ - (void)updateAnimationForPossibleVisibility - (void)displayLinkFired:(PINDisplayLink *)displayLink { PINAssertMain(); - CFTimeInterval timeBetweenLastFire; - if (_lastDisplayLinkFire == 0) { - timeBetweenLastFire = 0; - } else { - timeBetweenLastFire = CACurrentMediaTime() - self.lastDisplayLinkFire; - } - - self.lastDisplayLinkFire = CACurrentMediaTime(); +#if PIN_TARGET_MAC + CFTimeInterval timeBetweenLastFire = displayLink.duration; +#else + CFTimeInterval timeBetweenLastFire = displayLink.duration * displayLink.frameInterval; +#endif _playHead += timeBetweenLastFire; @@ -383,7 +377,7 @@ - (void)displayLinkFired:(PINDisplayLink *)displayLink if (frameImage == nil) { //Pause the display link until we get a file ready notification displayLink.paused = YES; - self.lastDisplayLinkFire = 0; + _playHead = MAX(_playHead - timeBetweenLastFire, 0); } else { if (_frameImage) { CGImageRelease(_frameImage); diff --git a/Source/Classes/PINDisplayLink.h b/Source/Classes/PINDisplayLink.h index 0b43e7bf..06269208 100644 --- a/Source/Classes/PINDisplayLink.h +++ b/Source/Classes/PINDisplayLink.h @@ -20,6 +20,7 @@ @property(getter=isPaused, nonatomic) BOOL paused; @property(nonatomic) NSInteger frameInterval; +@property(nonatomic, readonly) CFTimeInterval duration; @end #endif diff --git a/Source/Classes/PINDisplayLink.m b/Source/Classes/PINDisplayLink.m index 73124704..1c838c09 100644 --- a/Source/Classes/PINDisplayLink.m +++ b/Source/Classes/PINDisplayLink.m @@ -16,7 +16,7 @@ @interface PINDisplayLink () @property (nonatomic, readonly) NSRunLoop *runloop; @property (nonatomic, readonly) NSRunLoopMode mode; -- (void)displayLinkFired; +- (void)displayLinkFiredWithDuration:(CFTimeInterval)duration; @end @@ -27,8 +27,9 @@ static CVReturn displayLinkFired (CVDisplayLinkRef displayLink, CVOptionFlags *flagsOut, void *displayLinkContext) { + CFTimeInterval duration = inOutputTime->videoRefreshPeriod / (inOutputTime->videoTimeScale * inOutputTime->rateScalar); PINDisplayLink *link = (__bridge PINDisplayLink *)displayLinkContext; - [link displayLinkFired]; + [link displayLinkFiredWithDuration:duration]; return kCVReturnSuccess; } @@ -38,6 +39,7 @@ @implementation PINDisplayLink BOOL _paused; NSInteger _frameInterval; + CFTimeInterval _duration; } + (PINDisplayLink *)displayLinkWithTarget:(id)target selector:(SEL)sel @@ -63,9 +65,10 @@ - (void)dealloc } } -- (void)displayLinkFired +- (void)displayLinkFiredWithDuration:(CFTimeInterval)duration { dispatch_async(dispatch_get_main_queue(), ^{ + self.duration = duration; [self.runloop performSelector:self.selector target:self.target argument:self order:NSUIntegerMax modes:@[self.mode]]; }); } @@ -111,6 +114,18 @@ - (void)setPaused:(BOOL)paused } } +- (CFTimeInterval)duration +{ + PINAssertMain(); + return _duration; +} + +- (void)setDuration:(CFTimeInterval)duration +{ + PINAssertMain(); + _duration = duration; +} + - (NSInteger)frameInterval { PINAssertMain();