Skip to content

Commit

Permalink
Fix for completion block crash
Browse files Browse the repository at this point in the history
  • Loading branch information
brandon_withrow committed Aug 15, 2017
1 parent 88d38f3 commit 9b6d3c9
Show file tree
Hide file tree
Showing 9 changed files with 65 additions and 41 deletions.
4 changes: 2 additions & 2 deletions Example/Podfile.lock
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
PODS:
- lottie-ios (2.0.3)
- lottie-ios (2.0.4)

DEPENDENCIES:
- lottie-ios (from `../`)
Expand All @@ -9,7 +9,7 @@ EXTERNAL SOURCES:
:path: "../"

SPEC CHECKSUMS:
lottie-ios: 445f77c7f661f95587e49095a1ac7de43f0da896
lottie-ios: a5100b16eb8e5ea92019e0c92c405889cb580289

PODFILE CHECKSUM: fdbd59f361db8744871f0e9a0b3f94e0b7b8ca6b

Expand Down
4 changes: 2 additions & 2 deletions Example/Pods/Local Podspecs/lottie-ios.podspec.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Example/Pods/Manifest.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Example/lottie-ios.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -949,7 +949,7 @@
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "lottie-ios/lottie-ios-Prefix.pch";
INFOPLIST_FILE = "lottie-ios/lottie-ios-Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
IPHONEOS_DEPLOYMENT_TARGET = 8.1;
MODULE_NAME = ExampleApp;
PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = "$(TARGET_NAME)";
Expand All @@ -966,7 +966,7 @@
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "lottie-ios/lottie-ios-Prefix.pch";
INFOPLIST_FILE = "lottie-ios/lottie-ios-Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
IPHONEOS_DEPLOYMENT_TARGET = 8.1;
MODULE_NAME = ExampleApp;
PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = "$(TARGET_NAME)";
Expand Down
9 changes: 8 additions & 1 deletion Example/lottie-ios/AnimationExplorerViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -224,14 +224,21 @@ - (void)_play:(UIBarButtonItem *)button {
[self resetButton:button highlighted:NO];
[self.laAnimation pause];
} else {

CADisplayLink *displayLink =[CADisplayLink displayLinkWithTarget:self selector:@selector(_updateSlider)] ;
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
[self resetButton:button highlighted:YES];
[self.laAnimation playWithCompletion:^(BOOL animationFinished) {
self.slider.value = self.laAnimation.animationProgress;
[displayLink invalidate];
[self resetButton:button highlighted:NO];
}];
}
}

- (void)_updateSlider {
self.slider.value = self.laAnimation.animationProgress;
}

- (void)_loop:(UIBarButtonItem *)button {
self.laAnimation.loopAnimation = !self.laAnimation.loopAnimation;
[self resetButton:button highlighted:self.laAnimation.loopAnimation];
Expand Down
25 changes: 17 additions & 8 deletions lottie-ios/Classes/AnimatableLayers/LOTLayerContainer.m
Original file line number Diff line number Diff line change
Expand Up @@ -178,29 +178,38 @@ - (void)_setImageForAsset:(LOTAsset *)asset {
// MARK - Animation

+ (BOOL)needsDisplayForKey:(NSString *)key {
BOOL needsDisplay = [super needsDisplayForKey:key];

if ([key isEqualToString:@"currentFrame"]) {
needsDisplay = YES;
return YES;
}

return needsDisplay;
return [super needsDisplayForKey:key];
}

-(id<CAAction>)actionForKey:(NSString *)event {
if([event isEqualToString:@"currentFrame"]) {
CABasicAnimation *theAnimation = [CABasicAnimation
animationWithKeyPath:event];
theAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
theAnimation.fromValue = [[self presentationLayer] valueForKey:event];
return theAnimation;
}
return [super actionForKey:event];
}

- (id)initWithLayer:(id)layer {
if (self = [super initWithLayer:layer]) {
if ([layer isKindOfClass:[LOTLayerContainer class]]) {
LOTLayerContainer *other = (LOTLayerContainer *)layer;
self.currentFrame = other.currentFrame;
}
}
return self;
}

- (void)display {
LOTLayerContainer *presentation = (LOTLayerContainer *)self.presentationLayer;
if (presentation == nil) {
presentation = self;
LOTLayerContainer *presentation = self;
if (self.animationKeys.count &&
self.presentationLayer) {
presentation = (LOTLayerContainer *)self.presentationLayer;
}
[self displayWithFrame:presentation.currentFrame];
}
Expand Down
52 changes: 30 additions & 22 deletions lottie-ios/Classes/Private/LOTAnimationView.m
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@
#import "LOTCompositionContainer.h"

@implementation LOTAnimationView {
CABasicAnimation *_playAnimation;
LOTCompositionContainer *_compContainer;
NSNumber *_playRangeStartFrame;
NSNumber *_playRangeEndFrame;
CGFloat _playRangeStartProgress;
CGFloat _playRangeEndProgress;
NSBundle *_bundle;
CGFloat _animationProgress;
}

# pragma mark - Convenience Initializers
Expand Down Expand Up @@ -200,11 +200,8 @@ - (void)_restoreState {
}

- (void)_removeCurrentAnimationIfNecessary {
_playAnimation.speed = 0;
_isAnimationPlaying = NO;
_playAnimation.delegate = nil;
[_compContainer removeAllAnimations];
_playAnimation = nil;
}

- (CGFloat)_progressForFrame:(NSNumber *)frame {
Expand All @@ -225,8 +222,9 @@ - (NSNumber *)_frameForProgress:(CGFloat)progress {

- (void)_callCompletionIfNecessary:(BOOL)complete {
if (self.completionBlock) {
self.completionBlock(complete);
LOTAnimationCompletionBlock completion = self.completionBlock;
self.completionBlock = nil;
completion(complete);
}
}

Expand Down Expand Up @@ -314,21 +312,18 @@ - (void)playFromFrame:(nonnull NSNumber *)fromStartFrame
animation.autoreverses = _autoReverseAnimation;
animation.delegate = self;
animation.removedOnCompletion = NO;
_playAnimation = animation;
_playAnimation.beginTime = CACurrentMediaTime() - offset;
animation.beginTime = CACurrentMediaTime() - offset;
[_compContainer addAnimation:animation forKey:@"play"];
_isAnimationPlaying = YES;
}

#pragma mark - Other Time Controls

- (void)stop {
if (!_sceneModel ||
!_isAnimationPlaying) {
_isAnimationPlaying = NO;
return;
_isAnimationPlaying = NO;
if (_sceneModel) {
[self setProgressWithFrame:_sceneModel.startFrame callCompletionIfNecessary:YES];
}
[self setProgressWithFrame:_sceneModel.startFrame callCompletionIfNecessary:YES];
}

- (void)pause {
Expand Down Expand Up @@ -469,12 +464,22 @@ - (CGFloat)animationDuration {
if (!_sceneModel) {
return 0;
}
if (_playAnimation) {
return _playAnimation.duration;
CAAnimation *play = [_compContainer animationForKey:@"play"];
if (play) {
return play.duration;
}
return (_sceneModel.endFrame.floatValue - _sceneModel.startFrame.floatValue) / _sceneModel.framerate.floatValue;
}

- (CGFloat)animationProgress {
if (_isAnimationPlaying &&
_compContainer.presentationLayer) {
CGFloat activeProgress = [self _progressForFrame:[(LOTCompositionContainer *)_compContainer.presentationLayer currentFrame]];
return activeProgress;
}
return _animationProgress;
}

# pragma mark - Overrides

#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
Expand All @@ -495,9 +500,8 @@ - (CGFloat)animationDuration {
#define LOTViewContentModeBottomRight UIViewContentModeBottomRight

- (void)removeFromSuperview {
[self _callCompletionIfNecessary:NO];
[self _removeCurrentAnimationIfNecessary];
[super removeFromSuperview];
[self _callCompletionIfNecessary:NO];
}

- (void)setContentMode:(LOTViewContentMode)contentMode {
Expand Down Expand Up @@ -592,13 +596,17 @@ - (void)_layout {
# pragma mark - CAANimationDelegate

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)complete {
if (!_isAnimationPlaying || !complete) {
[_compContainer displayWithFrame:_compContainer.currentFrame forceUpdate:YES];
if ([_compContainer animationForKey:@"play"] == anim &&
[anim isKindOfClass:[CABasicAnimation class]]) {
CABasicAnimation *playAnimation = (CABasicAnimation *)anim;
NSNumber *frame = _compContainer.presentationLayer.currentFrame;
if (complete) {
frame = (NSNumber *)playAnimation.toValue;
}
[self _removeCurrentAnimationIfNecessary];
[self setProgressWithFrame:frame callCompletionIfNecessary:NO];
[self _callCompletionIfNecessary:complete];
}
if (!_isAnimationPlaying || !complete || ![anim isKindOfClass:[CABasicAnimation class]]) return;
[self _removeCurrentAnimationIfNecessary];
[self setProgressWithFrame:_playRangeEndFrame callCompletionIfNecessary:NO];
[self _callCompletionIfNecessary:complete];
}

@end

0 comments on commit 9b6d3c9

Please sign in to comment.