Added LoadFromUrl api

This commit is contained in:
Brandon Withrow
2017-01-06 14:32:46 -08:00
parent bfc0f9d4c4
commit ae57c41b08
16 changed files with 129 additions and 253 deletions

View File

@@ -62,8 +62,6 @@
48E7749D1D4AABDA0029FC2D /* LAShapeCircle.m in Sources */ = {isa = PBXBuildFile; fileRef = 48E774771D4AABDA0029FC2D /* LAShapeCircle.m */; };
48E7749E1D4AABDA0029FC2D /* LAShapeRectangle.h in Headers */ = {isa = PBXBuildFile; fileRef = 48E774781D4AABDA0029FC2D /* LAShapeRectangle.h */; };
48E7749F1D4AABDA0029FC2D /* LAShapeRectangle.m in Sources */ = {isa = PBXBuildFile; fileRef = 48E774791D4AABDA0029FC2D /* LAShapeRectangle.m */; };
48E774A71D4AABF00029FC2D /* BWMath.h in Headers */ = {isa = PBXBuildFile; fileRef = 48E774A11D4AABF00029FC2D /* BWMath.h */; };
48E774A81D4AABF00029FC2D /* BWMath.m in Sources */ = {isa = PBXBuildFile; fileRef = 48E774A21D4AABF00029FC2D /* BWMath.m */; };
48E774A91D4AABF00029FC2D /* UIColor+Expanded.h in Headers */ = {isa = PBXBuildFile; fileRef = 48E774A31D4AABF00029FC2D /* UIColor+Expanded.h */; };
48E774AA1D4AABF00029FC2D /* UIColor+Expanded.m in Sources */ = {isa = PBXBuildFile; fileRef = 48E774A41D4AABF00029FC2D /* UIColor+Expanded.m */; };
48E774AB1D4AABF00029FC2D /* CGGeometryAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 48E774A51D4AABF00029FC2D /* CGGeometryAdditions.h */; };
@@ -129,8 +127,6 @@
48E774771D4AABDA0029FC2D /* LAShapeCircle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LAShapeCircle.m; sourceTree = "<group>"; };
48E774781D4AABDA0029FC2D /* LAShapeRectangle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LAShapeRectangle.h; sourceTree = "<group>"; };
48E774791D4AABDA0029FC2D /* LAShapeRectangle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LAShapeRectangle.m; sourceTree = "<group>"; };
48E774A11D4AABF00029FC2D /* BWMath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BWMath.h; sourceTree = "<group>"; };
48E774A21D4AABF00029FC2D /* BWMath.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BWMath.m; sourceTree = "<group>"; };
48E774A31D4AABF00029FC2D /* UIColor+Expanded.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIColor+Expanded.h"; sourceTree = "<group>"; };
48E774A41D4AABF00029FC2D /* UIColor+Expanded.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIColor+Expanded.m"; sourceTree = "<group>"; };
48E774A51D4AABF00029FC2D /* CGGeometryAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CGGeometryAdditions.h; sourceTree = "<group>"; };
@@ -177,7 +173,6 @@
48E7742B1D4AAB070029FC2D /* Lottie.h */,
48E7742D1D4AAB070029FC2D /* Info.plist */,
);
name = Lottie;
path = Lottie;
sourceTree = "<group>";
};
@@ -250,8 +245,6 @@
48E774AD1D4AABF50029FC2D /* Helpers */ = {
isa = PBXGroup;
children = (
48E774A11D4AABF00029FC2D /* BWMath.h */,
48E774A21D4AABF00029FC2D /* BWMath.m */,
48E774A31D4AABF00029FC2D /* UIColor+Expanded.h */,
48E774A41D4AABF00029FC2D /* UIColor+Expanded.m */,
48E774A51D4AABF00029FC2D /* CGGeometryAdditions.h */,
@@ -289,7 +282,6 @@
48E7747A1D4AABDA0029FC2D /* LAModels.h in Headers */,
48E774801D4AABDA0029FC2D /* LAAnimatableNumberValue.h in Headers */,
48E774901D4AABDA0029FC2D /* LAShapeGroup.h in Headers */,
48E774A71D4AABF00029FC2D /* BWMath.h in Headers */,
48E7744B1D4AABB70029FC2D /* LAGroupLayerView.h in Headers */,
48E774921D4AABDA0029FC2D /* LAShapeStroke.h in Headers */,
48E774861D4AABDA0029FC2D /* LAAnimatableScaleValue.h in Headers */,
@@ -386,7 +378,6 @@
48E774971D4AABDA0029FC2D /* LAShapeFill.m in Sources */,
48E774991D4AABDA0029FC2D /* LAShapeTransform.m in Sources */,
48E7748D1D4AABDA0029FC2D /* LALayer.m in Sources */,
48E774A81D4AABF00029FC2D /* BWMath.m in Sources */,
48E7747F1D4AABDA0029FC2D /* LAAnimatablePointValue.m in Sources */,
48E7744C1D4AABB70029FC2D /* LAGroupLayerView.m in Sources */,
48E774931D4AABDA0029FC2D /* LAShapeStroke.m in Sources */,

View File

@@ -1,20 +0,0 @@
//
// BWMath.h
// Perfective
//
// Created by Brandon Withrow on 5/11/14.
// Copyright (c) 2014 Brandon Withrow. All rights reserved.
//
#import <GLKit/GLKit.h>
CGFloat DistanceBetweenTwoPoints(CGPoint point1, CGPoint point2);
CGPoint IntersectionOfPoints(CGPoint topLeft, CGPoint bottomRight, CGPoint topRight, CGPoint bottomLeft);
CGRect BoundingBoxForPoints(CGPoint topLeft, CGPoint topRight, CGPoint bottomLeft, CGPoint bottomRight);
CGFloat RadiansToDegrees(CGFloat radians);
CGFloat DegreesToRadians(CGFloat degrees);
CGPoint PointOnCircleAtAngle(CGFloat circleRadius, CGPoint circleCenter, CGFloat angleInDegrees);
CGFloat RemapValue(CGFloat value, CGFloat low1, CGFloat high1, CGFloat low2, CGFloat high2 );
CGFloat LoopFloat(CGFloat value, CGFloat min, CGFloat max);

View File

@@ -1,74 +0,0 @@
//
// BWMath.m
// Perfective
//
// Created by Brandon Withrow on 5/11/14.
// Copyright (c) 2014 Brandon Withrow. All rights reserved.
//
#import "BWMath.h"
CGPoint IntersectionOfPoints(CGPoint topLeft, CGPoint bottomRight, CGPoint topRight, CGPoint bottomLeft) {
CGFloat d = (bottomRight.x - topLeft.x)*(bottomLeft.y - topRight.y) - (bottomRight.y - topLeft.y)*(bottomLeft.x - topRight.x);
if (d == 0)
return CGPointZero; // parallel lines
CGFloat u = ((topRight.x - topLeft.x)*(bottomLeft.y - topRight.y) - (topRight.y - topLeft.y)*(bottomLeft.x - topRight.x))/d;
CGFloat v = ((topRight.x - topLeft.x)*(bottomRight.y - topLeft.y) - (topRight.y - topLeft.y)*(bottomRight.x - topLeft.x))/d;
if (u < 0.0 || u > 1.0)
return CGPointZero; // intersection point not between topLeft and bottomRight
if (v < 0.0 || v > 1.0)
return CGPointZero; // intersection point not between topRight and bottomLeft
CGPoint intersection;
intersection.x = topLeft.x + u * (bottomRight.x - topLeft.x);
intersection.y = topLeft.y + u * (bottomRight.y - topLeft.y);
return intersection;
}
CGRect BoundingBoxForPoints(CGPoint topLeft, CGPoint topRight, CGPoint bottomLeft, CGPoint bottomRight) {
CGRect boundingBox = CGRectZero;
boundingBox.origin.x = topLeft.x < bottomLeft.x ? topLeft.x : bottomLeft.x;
boundingBox.origin.y = topLeft.y < topRight.y ? topLeft.y : topRight.y;
boundingBox.size.width = (topRight.x > bottomRight.x ? topRight.x : bottomRight.x) - boundingBox.origin.x;
boundingBox.size.height = (bottomLeft.y > bottomRight.y ? bottomLeft.y : bottomRight.y) - boundingBox.origin.y;
return boundingBox;
}
CGFloat sqr(CGFloat num) {
return pow(num, 2);
}
CGFloat RadiansToDegrees(CGFloat radians) {
return ( ( radians ) * ( 180.0 / M_PI ) );
}
CGFloat DegreesToRadians(CGFloat degrees) {
return ( ( degrees ) / 180.0 * M_PI );
}
CGPoint PointOnCircleAtAngle(CGFloat circleRadius, CGPoint circleCenter, CGFloat angleInDegrees) {
// x = cx + r * cos(a)
// y = cy + r * sin(a)
//x = cx + (r * cos(a)) and y = cy + (r * sin(a))
CGFloat radians = DegreesToRadians(angleInDegrees);
return CGPointMake(circleCenter.x + (circleRadius * cos(radians)),
circleCenter.y + (circleRadius * sin(radians)));
}
CGFloat RemapValue(CGFloat value, CGFloat low1, CGFloat high1, CGFloat low2, CGFloat high2 ) {
return low2 + (value - low1) * (high2 - low2) / (high1 - low1);
}
CGFloat LoopFloat(CGFloat value, CGFloat min, CGFloat max) {
CGFloat loopedValue;
// Get to base zero.
CGFloat offsetMax = max - min;
CGFloat offsetValue = value - min;
CGFloat valueDiffFactor = floor(offsetValue / offsetMax);
CGFloat baseZeroLooped = offsetValue - (valueDiffFactor * offsetMax);
loopedValue = baseZeroLooped + min;
return loopedValue;
}

View File

@@ -98,3 +98,7 @@ GLKMatrix4 GLKMatrix4FromCATransform(CATransform3D xform);
CATransform3D CATransform3DFromGLKMatrix4(GLKMatrix4 xform);
CATransform3D CATransform3DSlerpToTransform(CATransform3D fromXorm, CATransform3D toXform, CGFloat amount );
CGFloat DegreesToRadians(CGFloat degrees);
CGFloat RemapValue(CGFloat value, CGFloat low1, CGFloat high1, CGFloat low2, CGFloat high2 );

View File

@@ -411,4 +411,12 @@ CGFloat CGPointDistanceFromPoint(CGPoint point1, CGPoint point2) {
CGFloat yDist = (point2.y - point1.y);
CGFloat distance = sqrt((xDist * xDist) + (yDist * yDist));
return distance;
}
}
CGFloat DegreesToRadians(CGFloat degrees) {
return ( ( degrees ) / 180.0 * M_PI );
}
CGFloat RemapValue(CGFloat value, CGFloat low1, CGFloat high1, CGFloat low2, CGFloat high2 ) {
return low2 + (value - low1) * (high2 - low2) / (high1 - low1);
}

View File

@@ -7,7 +7,7 @@
//
#import "LAAnimatableNumberValue.h"
#import "BWMath.h"
#import "LAHelpers.h"
@interface LAAnimatableNumberValue ()

View File

@@ -7,7 +7,6 @@
//
#import "LAAnimatablePointValue.h"
#import "BWMath.h"
#import "CGGeometryAdditions.h"
@interface LAAnimatablePointValue ()

View File

@@ -7,7 +7,6 @@
//
#import "LAAnimatableShapeValue.h"
#import "BWMath.h"
#import "CGGeometryAdditions.h"
@interface LAAnimatableShapeValue ()

View File

@@ -6,15 +6,6 @@
// Copyright © 2015 Brandon Withrow. All rights reserved.
//
// TODO
// - Support repeater objects
// - Animated Button
// - Merged Paths
// - Line start offset
// - Round Rect with dashed lines
#import <UIKit/UIKit.h>
@interface LAAnimationView : UIView
@@ -22,6 +13,8 @@
+ (instancetype)animationNamed:(NSString *)animationName;
+ (instancetype)animationFromJSON:(NSDictionary *)animationJSON;
- (instancetype)initWithContentsOfURL:(NSURL *)url;
@property (nonatomic, readonly) BOOL isAnimationPlaying;
@property (nonatomic, assign) BOOL loopAnimation;
@property (nonatomic, assign) CGFloat animationProgress;

View File

@@ -122,7 +122,7 @@ const NSTimeInterval singleFrameTimeValue = 1.0 / 60.0;
}
- (BOOL)animationIsPlaying {
if (_animationIsPlaying && !_loopAnimation) {
if (_animationIsPlaying && !_loopAnimation && _layer) {
CGFloat timeDiff = CACurrentMediaTime() - _startTimeAbsolute;
if (timeDiff > (_animationDuration * _animationSpeed)) {
_animationIsPlaying = NO;
@@ -159,23 +159,80 @@ const NSTimeInterval singleFrameTimeValue = 1.0 / 60.0;
- (instancetype)initWithModel:(LAComposition *)model {
self = [super initWithFrame:model.compBounds];
if (self) {
_sceneModel = model;
_animationContainer = [CALayer new];
_animationContainer.frame = self.bounds;
_animationContainer.fillMode = kCAFillModeForwards;
_animationContainer.masksToBounds = YES;
[self.layer addSublayer:_animationContainer];
[self _buildSubviewsFromModel];
self.clipsToBounds = YES;
[self _initializeAnimationContainer];
[self _setupWithSceneModel:model restoreAnimationState:NO];
}
return self;
}
_animationState = [[LAAnimationState alloc] initWithDuration:self.sceneModel.timeDuration + singleFrameTimeValue layer:_animationContainer];
- (instancetype)initWithContentsOfURL:(NSURL *)url {
self = [super initWithFrame:CGRectZero];
if (self) {
[self _initializeAnimationContainer];
_animationState = [[LAAnimationState alloc] initWithDuration:singleFrameTimeValue layer:nil];
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
NSData *animationData = [NSData dataWithContentsOfURL:url];
if (!animationData) {
return;
}
NSError *error;
NSDictionary *animationJSON = [NSJSONSerialization JSONObjectWithData:animationData
options:0 error:&error];
if (error || !animationJSON) {
return;
}
LAComposition *laScene = [[LAComposition alloc] initWithJSON:animationJSON];
dispatch_async(dispatch_get_main_queue(), ^(void){
[self _setupWithSceneModel:laScene restoreAnimationState:YES];
});
});
}
return self;
}
# pragma mark - Internal Methods
- (void)_initializeAnimationContainer {
_animationContainer = [CALayer new];
_animationContainer.fillMode = kCAFillModeForwards;
_animationContainer.masksToBounds = YES;
[self.layer addSublayer:_animationContainer];
self.clipsToBounds = YES;
}
- (void)_setupWithSceneModel:(LAComposition *)model restoreAnimationState:(BOOL)restoreAnimation {
_sceneModel = model;
[self _buildSubviewsFromModel];
LAAnimationState *oldState = _animationState;
_animationState = [[LAAnimationState alloc] initWithDuration:_sceneModel.timeDuration + singleFrameTimeValue layer:_animationContainer];
NSLog(@"Animation Loaded");
// return;
if (restoreAnimation && oldState) {
[self setLoopAnimation:oldState.loopAnimation];
[self setAnimationSpeed:oldState.animationSpeed];
[self setAnimationProgress:oldState.animatedProgress];
if (oldState.animationIsPlaying) {
[self play];
}
}
}
- (void)_buildSubviewsFromModel {
if (_layerMap) {
_layerMap = nil;
[_animationContainer removeAllAnimations];
[_animationContainer.sublayers makeObjectsPerformSelector:@selector(removeFromSuperlayer)];
}
_animationContainer.transform = CATransform3DIdentity;
_animationContainer.bounds = _sceneModel.compBounds;
NSMutableDictionary *layerMap = [NSMutableDictionary dictionary];
NSArray *reversedItems = [[_sceneModel.layers reverseObjectEnumerator] allObjects];
@@ -204,14 +261,27 @@ const NSTimeInterval singleFrameTimeValue = 1.0 / 60.0;
}
- (void)playWithCompletion:(void (^)(void))completion {
if (_animationState.animationIsPlaying == NO) {
if (completion) {
self.completionBlock = completion;
}
if (_sceneModel == nil) {
[_animationState setAnimationIsPlaying:YES];
return;
}
if (_animationState.animationIsPlaying == NO) {
[_animationState setAnimationIsPlaying:YES];
[self startDisplayLink];
}
}
- (void)pause {
if (_sceneModel == nil) {
[_animationState setAnimationIsPlaying:NO];
return;
}
if (_animationState.animationIsPlaying) {
[_animationState setAnimationIsPlaying:NO];
[self stopDisplayLink];
@@ -291,6 +361,11 @@ const NSTimeInterval singleFrameTimeValue = 1.0 / 60.0;
- (void)layoutSubviews {
[super layoutSubviews];
if (_sceneModel == nil) {
_animationContainer.bounds = self.bounds;
return;
}
CGPoint centerPoint = CGRectGetCenterPoint(self.bounds);
CATransform3D xform;
@@ -320,7 +395,8 @@ const NSTimeInterval singleFrameTimeValue = 1.0 / 60.0;
[CATransaction begin];
[CATransaction setDisableActions:YES];
_animationContainer.transform = CATransform3DIdentity;
_animationContainer.bounds = _sceneModel.compBounds;
_animationContainer.transform = xform;
_animationContainer.position = centerPoint;
[CATransaction commit];

View File

@@ -8,7 +8,6 @@
#import "LAEllipseShapeLayer.h"
#import "CAAnimationGroup+LAAnimatableGroup.h"
#import "BWMath.h"
const CGFloat kEllipseControlPointPercentage = 0.55228;

View File

@@ -9,7 +9,6 @@
#ifndef LAHelpers_h
#define LAHelpers_h
#import "BWMath.h"
#import "UIColor+Expanded.h"
#import "CGGeometryAdditions.h"

View File

@@ -10,7 +10,7 @@
#import "LAAnimatableNumberValue.h"
#import "LAAnimatablePointValue.h"
#import "LAAnimatableScaleValue.h"
#import "BWMath.h"
#import "LAHelpers.h"
@implementation LAShapeTransform

View File

@@ -19,13 +19,13 @@
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "Lotte/Lotte/LALayerView.m"
timestampString = "505347634.023659"
filePath = "Lottie/Lottie/LAAnimationView.m"
timestampString = "505434485.581579"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "101"
endingLineNumber = "101"
landmarkName = "-_setupViewFromModel"
startingLineNumber = "272"
endingLineNumber = "272"
landmarkName = "-playWithCompletion:"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
@@ -35,125 +35,13 @@
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "Lotte/Lotte/LAMaskLayer.m"
timestampString = "505348188.125551"
filePath = "Lottie/Lottie/LAAnimationView.m"
timestampString = "505434507.953032"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "29"
endingLineNumber = "29"
landmarkName = "-_setupViewFromModel"
landmarkType = "7">
<Locations>
<Location
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
symbolName = "-[LAMaskLayer _setupViewFromModel]"
moduleName = "Lotte"
usesParentBreakpointCondition = "Yes"
urlString = "file:///Users/brandonwithrow/Coding/LotteAnimator/Lotte/Lotte/LAMaskLayer.m"
timestampString = "505349198.3566"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "30"
endingLineNumber = "30"
offsetFromSymbolStart = "92">
</Location>
<Location
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
symbolName = "-[LAMaskLayer _setupViewFromModel]"
moduleName = "Lotte"
usesParentBreakpointCondition = "Yes"
urlString = "file:///Users/brandonwithrow/Coding/LotteAnimator/Lotte/Lotte/LAMaskLayer.m"
timestampString = "505349198.359211"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "30"
endingLineNumber = "30"
offsetFromSymbolStart = "104">
</Location>
</Locations>
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "Lotte/Lotte/LAShapeCircle.m"
timestampString = "505348704.526323"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "24"
endingLineNumber = "24"
landmarkName = "-_mapFromJSON:frameRate:"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "Lotte/Lotte/LAEllipseShapeLayer.m"
timestampString = "505348789.03431"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "178"
endingLineNumber = "178"
landmarkName = "-_buildAnimation"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "Lotte/Lotte/LAAnimatableShapeValue.m"
timestampString = "505349148.801503"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "46"
endingLineNumber = "46"
landmarkName = "-_buildAnimationForKeyframes:closed:"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "Lotte/Lotte/LAAnimatableShapeValue.m"
timestampString = "505349179.93757"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "144"
endingLineNumber = "144"
landmarkName = "-_bezierShapeFromValue:closed:"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "Lotte/Lotte/LARectShapeLayer.m"
timestampString = "505349324.271057"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "96"
endingLineNumber = "96"
landmarkName = "-initWithRectShape:fill:stroke:transform:withDuration:"
startingLineNumber = "213"
endingLineNumber = "213"
landmarkName = "-_setupWithSceneModel:restoreAnimationState:"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>

View File

@@ -99,6 +99,15 @@
[self _updatePlayButtonTitle];
}
- (void)_openFileAtURL:(NSURL *)url {
currentAnimation = [[LAAnimationView alloc] initWithContentsOfURL:url];
currentAnimation.contentMode = UIViewContentModeScaleAspectFit;
[self.view addSubview:currentAnimation];
[currentAnimation play];
[self _updatePlayButtonTitle];
[self.view setNeedsLayout];
}
- (void)_openFileAtPath:(NSString *)filePath {
NSError *error;
NSData *jsonData = [[NSData alloc] initWithContentsOfFile:filePath];

View File

@@ -2,6 +2,11 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>