├── Demo
├── GLDTween.xcodeproj
│ ├── project.xcworkspace
│ │ └── contents.xcworkspacedata
│ └── project.pbxproj
├── GLDTween
│ ├── AppDelegate.h
│ ├── main.m
│ ├── TouchDemo
│ │ ├── TouchDemoViewController.h
│ │ └── TouchDemoViewController.m
│ ├── Images.xcassets
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ ├── Info.plist
│ ├── AppDelegate.m
│ └── Base.lproj
│ │ ├── LaunchScreen.xib
│ │ └── Main.storyboard
└── GLDTweenTests
│ ├── Info.plist
│ └── GLDTweenTests.m
├── GLDTween
├── GLDTweenBlock.h
├── GLDTweenTween.m
├── GLDTweenSelector.h
├── GLDTweenBlock.m
├── Plugins
│ ├── GLDTweenPropertyPlugin.h
│ ├── GLDEasingPlugin.h
│ ├── GLDTweenPropertyPlugin.m
│ └── GLDEasingPlugin.m
├── GLDTweenSelector.m
├── GLDTweenProperty.h
├── GLDTweenTween.h
├── GLDTween.h
├── GLDTweenProperty.m
└── GLDTween.m
├── .gitignore
├── GLDTween.podspec
├── LICENSE
└── README.md
/Demo/GLDTween.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Demo/GLDTween/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // GLDTween
4 | //
5 | // Created by Takayuki Fukatsu on 2014/10/01.
6 | // Copyright (c) 2014 THE GUILD. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 |
12 | @interface AppDelegate : UIResponder
13 |
14 | @property (strong, nonatomic) UIWindow *window;
15 |
16 | @end
17 |
18 |
--------------------------------------------------------------------------------
/Demo/GLDTween/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // GLDTween
4 | //
5 | // Created by Takayuki Fukatsu on 2014/10/01.
6 | // Copyright (c) 2014 THE GUILD. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "AppDelegate.h"
11 |
12 |
13 | int main(int argc, char * argv[]) {
14 | @autoreleasepool {
15 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/GLDTween/GLDTweenBlock.h:
--------------------------------------------------------------------------------
1 | //
2 | // GLDTweenBlock.h
3 | // GLDTween
4 | //
5 | // Created by Takayuki Fukatsu on 2014/10/01.
6 | // Copyright (c) 2014 THE GUILD. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 |
12 | @interface GLDTweenBlock : NSObject
13 |
14 | @property (nonatomic, copy)void (^block)(void);
15 |
16 | - (id)initWithBlock:(void(^)(void))block;
17 | + (GLDTweenBlock *)block:(void(^)(void))block;
18 | - (void)execute;
19 |
20 | @end
21 |
--------------------------------------------------------------------------------
/Demo/GLDTween/TouchDemo/TouchDemoViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // TouchDemoViewController.h
3 | // GLDTween
4 | //
5 | // Created by Takayuki Fukatsu on 2014/10/03.
6 | // Copyright (c) 2014 THE GUILD. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 |
12 | @interface TouchDemoViewController : UIViewController
13 |
14 | @property (strong, nonatomic) IBOutlet UIView *box;
15 | @property (strong, nonatomic) IBOutlet UIPickerView *picker;
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/GLDTween/GLDTweenTween.m:
--------------------------------------------------------------------------------
1 | //
2 | // GLDTweenTween.m
3 | // GLDTween
4 | //
5 | // Created by Takayuki Fukatsu on 2014/10/01.
6 | // Copyright (c) 2014 THE GUILD. All rights reserved.
7 | //
8 |
9 | #import "GLDTweenTween.h"
10 |
11 |
12 | /**
13 | 実際のアニメーションを表現するクラス。
14 | */
15 | @implementation GLDTweenTween
16 |
17 |
18 | - (id)init {
19 | if (self = [super init]) {
20 | self.properties = [[NSMutableDictionary alloc] initWithCapacity:0];
21 | }
22 | return self;
23 | }
24 |
25 |
26 | @end
27 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | .DS_Store
4 |
5 | build/
6 | *.pbxuser
7 | !default.pbxuser
8 | *.mode1v3
9 | !default.mode1v3
10 | *.mode2v3
11 | !default.mode2v3
12 | *.perspectivev3
13 | !default.perspectivev3
14 | xcuserdata
15 | *.xccheckout
16 | *.moved-aside
17 | DerivedData
18 | *.hmap
19 | *.ipa
20 | *.xcuserstate
21 |
22 |
23 | # CocoaPods
24 | #
25 | # We recommend against adding the Pods directory to your .gitignore. However
26 | # you should judge for yourself, the pros and cons are mentioned at:
27 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
28 | #
29 |
30 | Pods/
31 |
--------------------------------------------------------------------------------
/GLDTween/GLDTweenSelector.h:
--------------------------------------------------------------------------------
1 | //
2 | // GLDTweenSelector.h
3 | // GLDTween
4 | //
5 | // Created by Takayuki Fukatsu on 2014/10/01.
6 | // Copyright (c) 2014 THE GUILD. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 |
12 | /**
13 | Simple Selector Wrapper for NSDictionary
14 | */
15 | @interface GLDTweenSelector : NSObject
16 |
17 | @property (strong, nonatomic) NSObject *target;
18 | @property (nonatomic) SEL selector;
19 |
20 | - (id)initWithSelector:(SEL)selector target:(NSObject *)target;
21 | - (void)perform;
22 | + (GLDTweenSelector *)selector:(SEL)selector withTarget:(NSObject *)target;
23 |
24 | @end
25 |
--------------------------------------------------------------------------------
/GLDTween/GLDTweenBlock.m:
--------------------------------------------------------------------------------
1 | //
2 | // GLDTweenBlock.m
3 | // GLDTween
4 | //
5 | // Created by Takayuki Fukatsu on 2014/10/01.
6 | // Copyright (c) 2014 THE GUILD. All rights reserved.
7 | //
8 |
9 | #import "GLDTweenBLock.h"
10 |
11 |
12 | @implementation GLDTweenBlock
13 |
14 |
15 | - (id)initWithBlock:(void(^)(void))block {
16 | if (self = [super init]) {
17 | self.block = block;
18 | }
19 | return self;
20 | }
21 |
22 |
23 | + (GLDTweenBlock *)block:(void(^)(void))block {
24 | return [[GLDTweenBlock alloc] initWithBlock:block];
25 | }
26 |
27 |
28 | - (void)execute {
29 | self.block();
30 | }
31 |
32 |
33 | @end
34 |
--------------------------------------------------------------------------------
/GLDTween.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = "GLDTween"
3 | s.version = "0.0.2"
4 | s.platform = :ios, "6.0"
5 | s.license = { :type => "MIT", :file => "LICENSE" }
6 | s.summary = "Fancy Animation Engine for iOS"
7 | s.description = <<-DESC
8 | iOS needs better animation engine. CAAnimation is not so handy, so we did.
9 | DESC
10 |
11 | s.homepage = "https://github.com/theguildjp/GLDTween"
12 | s.author = { "Takayuki Fukatsu" => "fukatsu@gmail.com" }
13 | s.social_media_url = "http://twitter.com/fladdict"
14 |
15 | s.requires_arc = true
16 | s.source = { :git => "https://github.com/theguildjp/GLDTween.git", :tag => "0.0.2" }
17 | s.source_files = "GLDTween/**/*.{h,m,swift}"
18 | end
19 |
--------------------------------------------------------------------------------
/Demo/GLDTween/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | }
33 | ],
34 | "info" : {
35 | "version" : 1,
36 | "author" : "xcode"
37 | }
38 | }
--------------------------------------------------------------------------------
/Demo/GLDTweenTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | jp.theguild.$(PRODUCT_NAME:rfc1034identifier)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/GLDTween/Plugins/GLDTweenPropertyPlugin.h:
--------------------------------------------------------------------------------
1 | //
2 | // GLDTweenPropertyPlugin.h
3 | // GLDTween
4 | //
5 | // Created by Takayuki Fukatsu on 2014/10/01.
6 | // Copyright (c) 2014 THE GUILD. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 | #import
12 | #import "GLDTweenProperty.h"
13 |
14 |
15 | @interface GLDTweenPropertyX : GLDTweenPropertyCGFloat
16 | @end
17 |
18 |
19 | @interface GLDTweenPropertyY : GLDTweenPropertyCGFloat
20 | @end
21 |
22 |
23 | @interface GLDTweenPropertyWidth : GLDTweenPropertyCGFloat
24 | @end
25 |
26 |
27 | @interface GLDTweenPropertyHeight : GLDTweenPropertyCGFloat
28 | @end
29 |
30 |
31 | @interface GLDTweenPropertyCenterX : GLDTweenPropertyCGFloat
32 | @end
33 |
34 |
35 | @interface GLDTweenPropertyCenterY : GLDTweenPropertyCGFloat
36 | @end
37 |
38 |
39 | @interface GLDTweenPropertyTransform3D : GLDTweenPropertyCATransform3D
40 | @end
41 |
--------------------------------------------------------------------------------
/GLDTween/GLDTweenSelector.m:
--------------------------------------------------------------------------------
1 | //
2 | // GLDTweenSelector.m
3 | // GLDTween
4 | //
5 | // Created by Takayuki Fukatsu on 2014/10/01.
6 | // Copyright (c) 2014 THE GUILD. All rights reserved.
7 | //
8 |
9 | #import "GLDTweenSelector.h"
10 |
11 |
12 | @implementation GLDTweenSelector
13 |
14 |
15 | - (id)initWithSelector:(SEL)selector target:(NSObject *)target {
16 | if (self = [super init]) {
17 | self.selector = selector;
18 | self.target = target;
19 | }
20 | return self;
21 | }
22 |
23 |
24 | + (GLDTweenSelector *)selector:(SEL)selector withTarget:(NSObject *)target {
25 | return [[GLDTweenSelector alloc] initWithSelector:selector target:target];
26 | }
27 |
28 |
29 | - (void)perform {
30 | if ([self.target respondsToSelector:self.selector]) {
31 | #pragma clang diagnostic push
32 | #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
33 | [self.target performSelector:self.selector withObject:nil];
34 | #pragma clang diagnostic pop
35 | }
36 | }
37 |
38 |
39 | @end
40 |
--------------------------------------------------------------------------------
/Demo/GLDTweenTests/GLDTweenTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // GLDTweenTests.m
3 | // GLDTweenTests
4 | //
5 | // Created by Takayuki Fukatsu on 2014/10/01.
6 | // Copyright (c) 2014 THE GUILD. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 |
13 | @interface GLDTweenTests : XCTestCase
14 | @end
15 |
16 |
17 | @implementation GLDTweenTests
18 |
19 |
20 | - (void)setUp {
21 | [super setUp];
22 | // Put setup code here. This method is called before the invocation of each test method in the class.
23 | }
24 |
25 |
26 | - (void)tearDown {
27 | // Put teardown code here. This method is called after the invocation of each test method in the class.
28 | [super tearDown];
29 | }
30 |
31 |
32 | - (void)testExample {
33 | // This is an example of a functional test case.
34 | XCTAssert(YES, @"Pass");
35 | }
36 |
37 |
38 | - (void)testPerformanceExample {
39 | // This is an example of a performance test case.
40 | [self measureBlock:^{
41 | // Put the code you want to measure the time of here.
42 | }];
43 | }
44 |
45 |
46 | @end
47 |
--------------------------------------------------------------------------------
/Demo/GLDTween/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | jp.theguild.$(PRODUCT_NAME:rfc1034identifier)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/GLDTween/GLDTweenProperty.h:
--------------------------------------------------------------------------------
1 | //
2 | // GLDTweenProperty.h
3 | // GLDTween
4 | //
5 | // Created by Takayuki Fukatsu on 2014/10/01.
6 | // Copyright (c) 2014 THE GUILD. All rights reserved.
7 | //
8 |
9 | #import "GLDEasingPlugin.h"
10 | #import
11 | #import
12 | #import
13 |
14 |
15 | @interface GLDTweenProperty : NSObject
16 |
17 | @property (strong, nonatomic) NSString *key;
18 | @property (strong, nonatomic, readonly) NSString *type;
19 | @property NSValue *startValue;
20 | @property NSValue *completeValue;
21 | // TODO: Implement
22 | @property (nonatomic, getter = isRounded) BOOL rounded;
23 |
24 | - (void)setStartValueForTarget:(NSObject *)target key:(NSString *)key;
25 | - (void)setTweenValueForTarget:(NSObject *)target key:(NSString *)key time:(float)t duration:(float)d ease:(GLDEasingFunction *)ease;
26 | - (void)setCompleteValueForTarget:(NSObject *)target key:(NSString *)key;
27 | - (void)updateStartValueForTarget:(NSObject *)target key:(NSString *)key;
28 | - (void)setValue:(NSValue *)value forTarget:(NSObject *)target key:(NSString *)key;
29 | - (id)valueForTarget:(NSObject *)target key:(NSString *)key;
30 |
31 | @end
32 |
33 |
34 | @interface GLDTweenPropertyCGFloat : GLDTweenProperty
35 | @end
36 |
37 |
38 | @interface GLDTweenPropertyCGPoint : GLDTweenProperty
39 | @end
40 |
41 |
42 | @interface GLDTweenPropertyCGSize : GLDTweenProperty
43 | @end
44 |
45 |
46 | @interface GLDTweenPropertyCGRect : GLDTweenProperty
47 | @end
48 |
49 |
50 | @interface GLDTweenPropertyCGAffineTransform : GLDTweenProperty
51 | @end
52 |
53 |
54 | @interface GLDTweenPropertyCATransform3D : GLDTweenProperty
55 | @end
56 |
--------------------------------------------------------------------------------
/GLDTween/GLDTweenTween.h:
--------------------------------------------------------------------------------
1 | //
2 | // GLDTweenTween.h
3 | // GLDTween
4 | //
5 | // Created by Takayuki Fukatsu on 2014/10/01.
6 | // Copyright (c) 2014 THE GUILD. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "GLDTweenSelector.h"
11 | #import "GLDTweenBlock.h"
12 |
13 |
14 | /**
15 | Animation Instance that runs on GLDTween Animation Engine
16 | */
17 | @interface GLDTweenTween : NSObject
18 |
19 | @property (strong, nonatomic) NSObject *target;
20 | @property (strong, nonatomic) NSMutableDictionary *properties;
21 | @property (strong, nonatomic) NSString *easing;
22 | @property (nonatomic) int repeat;
23 | @property (nonatomic) BOOL repeatsDelay;
24 | @property (nonatomic, getter = isRounded) BOOL rounded;
25 |
26 | //Interaction(Testing)
27 | @property (nonatomic) BOOL locksInteraction; //Ignore Interaction when add.
28 | @property (nonatomic) BOOL unlocksInteraction; //End Ignore Interaction when complete(or removed?)
29 |
30 | //Time
31 | @property (nonatomic) NSTimeInterval startTime;
32 | @property (nonatomic) NSTimeInterval completeTime;
33 | @property (nonatomic) NSTimeInterval pausedTime;
34 | @property (nonatomic) NSTimeInterval delay;
35 |
36 | //Flag
37 | @property (nonatomic, getter = isPaused) BOOL paused;
38 | @property (nonatomic, getter = hasStarted) BOOL started;
39 | @property (nonatomic, getter = hasCompleted) BOOL completed;
40 | @property (nonatomic) BOOL killFlag;
41 |
42 | //Blocks
43 | @property (strong, nonatomic) GLDTweenBlock *startBlock;
44 | @property (strong, nonatomic) GLDTweenBlock *updateBlock;
45 | @property (strong, nonatomic) GLDTweenBlock *repeatBlock;
46 | @property (strong, nonatomic) GLDTweenBlock *completionBlock;
47 |
48 |
49 | //Selectors
50 | @property (strong, nonatomic) GLDTweenSelector *startSelector;
51 | @property (strong, nonatomic) GLDTweenSelector *updateSelector;
52 | @property (strong, nonatomic) GLDTweenSelector *repeatSelector;
53 | @property (strong, nonatomic) GLDTweenSelector *completionSelector;
54 |
55 | @end
56 |
--------------------------------------------------------------------------------
/Demo/GLDTween/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // GLDTween
4 | //
5 | // Created by Takayuki Fukatsu on 2014/10/01.
6 | // Copyright (c) 2014 THE GUILD. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 |
11 |
12 | @implementation AppDelegate
13 |
14 |
15 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
16 | // Override point for customization after application launch.
17 | return YES;
18 | }
19 |
20 |
21 | - (void)applicationWillResignActive:(UIApplication *)application {
22 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
23 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
24 | }
25 |
26 |
27 | - (void)applicationDidEnterBackground:(UIApplication *)application {
28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
30 | }
31 |
32 |
33 | - (void)applicationWillEnterForeground:(UIApplication *)application {
34 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
35 | }
36 |
37 |
38 | - (void)applicationDidBecomeActive:(UIApplication *)application {
39 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
40 | }
41 |
42 |
43 | - (void)applicationWillTerminate:(UIApplication *)application {
44 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
45 | }
46 |
47 |
48 | @end
49 |
--------------------------------------------------------------------------------
/Demo/GLDTween/TouchDemo/TouchDemoViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // TouchDemoViewController.m
3 | // GLDTween
4 | //
5 | // Created by Takayuki Fukatsu on 2014/10/03.
6 | // Copyright (c) 2014 THE GUILD. All rights reserved.
7 | //
8 |
9 | #import "TouchDemoViewController.h"
10 | #import "GLDTween.h"
11 |
12 |
13 | @implementation TouchDemoViewController
14 |
15 |
16 | - (void)viewDidLoad {
17 | [super viewDidLoad];
18 |
19 | UITapGestureRecognizer *gesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(screenDidToucth:)];
20 | [self.view addGestureRecognizer:gesture];
21 |
22 | self.box.center = CGPointMake(0, 0);
23 | CGAffineTransform t = CGAffineTransformMakeTranslation(self.view.frame.size.width*0.5, self.view.frame.size.height*0.5);
24 | self.box.transform = t;
25 | }
26 |
27 |
28 | - (void)didReceiveMemoryWarning {
29 | [super didReceiveMemoryWarning];
30 | // Dispose of any resources that can be recreated.
31 | }
32 |
33 |
34 | - (void)screenDidToucth:(UITapGestureRecognizer*)gesture {
35 | CGPoint pt = [gesture locationInView:gesture.view];
36 | float rotation = arc4random() % 360;
37 | float scale = arc4random() % 100 / 50.0 + 0.5;
38 |
39 | CGAffineTransform t = CGAffineTransformIdentity;
40 | t = CGAffineTransformTranslate(t, pt.x, pt.y);
41 | t = CGAffineTransformRotate(t, rotation * M_PI / 180.0);
42 | t = CGAffineTransformScale(t, scale, scale);
43 |
44 | NSString* transition = [GLDTween easingNames][[self.picker selectedRowInComponent:0]];
45 |
46 | [GLDTween removeTween:self.box];
47 | [GLDTween addTween:self.box
48 | withParams:@{@"duration":@0.4,
49 | @"easing": transition,
50 | @"transform": [NSValue valueWithCGAffineTransform:t]}];
51 | }
52 |
53 |
54 | - (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
55 | }
56 |
57 |
58 | - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
59 | return 1;
60 | }
61 |
62 |
63 | - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
64 | return [GLDTween easingNames].count;
65 | }
66 |
67 |
68 | - (NSString*)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
69 | return [GLDTween easingNames][row];
70 | }
71 |
72 |
73 | @end
74 |
--------------------------------------------------------------------------------
/GLDTween/GLDTween.h:
--------------------------------------------------------------------------------
1 | //
2 | // GLDTween.h
3 | // GLDTween
4 | //
5 | // Created by Takayuki Fukatsu on 2014/10/01.
6 | // Copyright (c) 2014 THE GUILD. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 | #import
12 |
13 | #import "GLDTweenTween.h"
14 | #import "GLDTweenBlock.h"
15 | #import "GLDTweenSelector.h"
16 |
17 |
18 | //Easing Constants
19 | extern NSString *const GLDEasingNone;
20 | extern NSString *const GLDEasingInQuad;
21 | extern NSString *const GLDEasingOutQuad;
22 | extern NSString *const GLDEasingInOutQuad;
23 | extern NSString *const GLDEasingInCubic;
24 | extern NSString *const GLDEasingOutCubic;
25 | extern NSString *const GLDEasingInOutCubic;
26 | extern NSString *const GLDEasingInQuart;
27 | extern NSString *const GLDEasingOutQuart;
28 | extern NSString *const GLDEasingInOutQuart;
29 | extern NSString *const GLDEasingInQuint;
30 | extern NSString *const GLDEasingOutQuint;
31 | extern NSString *const GLDEasingInOutQuint;
32 | extern NSString *const GLDEasingInSine;
33 | extern NSString *const GLDEasingOutSine;
34 | extern NSString *const GLDEasingInOutSine;
35 | extern NSString *const GLDEasingInCirc;
36 | extern NSString *const GLDEasingOutCirc;
37 | extern NSString *const GLDEasingInOutCirc;
38 | extern NSString *const GLDEasingInExpo;
39 | extern NSString *const GLDEasingOutExpo;
40 | extern NSString *const GLDEasingInOutExpo;
41 | extern NSString *const GLDEasingInBack;
42 | extern NSString *const GLDEasingOutBack;
43 | extern NSString *const GLDEasingInOutBack;
44 | extern NSString *const GLDEasingInBounce;
45 | extern NSString *const GLDEasingOutBounce;
46 | extern NSString *const GLDEasingInOutBounce;
47 | extern NSString *const GLDEasingInElastic;
48 | extern NSString *const GLDEasingOutElastic;
49 | extern NSString *const GLDEasingInOutElastic;
50 |
51 | extern NSString *const GLDTweenParamDuration;
52 | extern NSString *const GLDTweenParamDelay;
53 | extern NSString *const GLDTweenParamRepeat;
54 | extern NSString *const GLDTweenParamEasing;
55 | extern NSString *const GLDTweenParamRounded;
56 | extern NSString *const GLDTweenParamStartSelector;
57 | extern NSString *const GLDTweenParamUpdateSelector;
58 | extern NSString *const GLDTweenParamRepeatSelector;
59 | extern NSString *const GLDTweenParamCompletionSelector;
60 | extern NSString *const GLDTweenParamStartBlock;
61 | extern NSString *const GLDTweenParamUpdateBlock;
62 | extern NSString *const GLDTweenParamRepeatBlock;
63 | extern NSString *const GLDTweenParamCompletionBlock;
64 | extern NSString *const GLDTweenParamRepeatsDelay;
65 | extern NSString *const GLDTweenParamLocksInteraction;
66 | extern NSString *const GLDTweenParamUnlocksInteraction;
67 |
68 |
69 | @interface GLDTween : NSObject
70 |
71 | //Addition
72 | + (BOOL)addTween:(NSObject *)target withParams:(NSDictionary *)params;
73 |
74 | //Remove
75 | + (BOOL)removeTween:(NSObject *)target;
76 | + (BOOL)removeTweens:(NSArray *)targets;
77 | + (BOOL)removeTween:(NSObject *)target withProps:(NSArray *)props;
78 | + (BOOL)removeAllTweens;
79 |
80 | //Pause
81 | + (BOOL)pauseTween:(NSObject *)target;
82 | + (BOOL)pauseTweens:(NSArray *)targets;
83 | + (BOOL)pauseAllTweens;
84 |
85 | //Resume
86 | + (BOOL)resumeTween:(NSObject *)target;
87 | + (BOOL)resumeTweens:(NSArray *)targets;
88 | + (BOOL)resumeAllTweens;
89 |
90 | //Plugin Management
91 | + (BOOL)registerEasingPlugin:(Class)class forKey:(NSString *)key;
92 | + (BOOL)registerSpecialPropertyPlugin:(Class)class forKey:(NSString *)key;
93 |
94 | //Utils
95 | + (NSArray *)easingNames;
96 |
97 | //Not implemented
98 | + (BOOL)isTweening:(NSObject *)target;
99 |
100 | @end
101 |
--------------------------------------------------------------------------------
/Demo/GLDTween/Base.lproj/LaunchScreen.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
20 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GLDTween is based on Zeh Femando's Tweener(MIT) and Robert Penners's easing equations((BSD).
2 | You can user this library for both personal and commercial project. Restriction is only displaying license text.
3 |
4 |
5 | The MIT License (MIT)
6 |
7 | Copyright (c) 2014 THE GUILD
8 |
9 | Permission is hereby granted, free of charge, to any person obtaining a copy
10 | of this software and associated documentation files (the "Software"), to deal
11 | in the Software without restriction, including without limitation the rights
12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 | copies of the Software, and to permit persons to whom the Software is
14 | furnished to do so, subject to the following conditions:
15 |
16 | The above copyright notice and this permission notice shall be included in all
17 | copies or substantial portions of the Software.
18 |
19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 | SOFTWARE.
26 |
27 |
28 |
29 | Tweener License
30 | Copyright (c) 2007 Zeh Fernando, Nate Chatellier, Arthur Debert
31 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
32 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
33 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 |
35 |
36 |
37 | Robert Penner Easing equations
38 | TERMS OF USE - EASING EQUATIONS
39 | Open source under the BSD License.
40 | Copyright © 2001 Robert Penner All rights reserved.
41 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
42 | Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
43 | Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
44 | Neither the name of the author nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission.
45 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46 |
--------------------------------------------------------------------------------
/Demo/GLDTween/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/GLDTween/Plugins/GLDEasingPlugin.h:
--------------------------------------------------------------------------------
1 | //
2 | // GLDEasingPlugin.h
3 | // GLDTween
4 | //
5 | // Created by Takayuki Fukatsu on 2014/10/01.
6 | // Copyright (c) 2014 THE GUILD. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 |
12 | @interface GLDEasingFunction : NSObject
13 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d;
14 | @end
15 |
16 | @interface GLDEasingFunctionNone : GLDEasingFunction
17 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d;
18 | @end
19 |
20 | @interface GLDEasingFunctionInQuad : GLDEasingFunction
21 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d;
22 | @end
23 |
24 | @interface GLDEasingFunctionOutQuad : GLDEasingFunction
25 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d;
26 | @end
27 |
28 | @interface GLDEasingFunctionInOutQuad: GLDEasingFunction
29 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d;
30 | @end
31 |
32 | @interface GLDEasingFunctionInCubic : GLDEasingFunction
33 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d;
34 | @end
35 |
36 | @interface GLDEasingFunctionOutCubic : GLDEasingFunction
37 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d;
38 | @end
39 |
40 | @interface GLDEasingFunctionInOutCubic: GLDEasingFunction
41 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d;
42 | @end
43 |
44 | @interface GLDEasingFunctionInQuart : GLDEasingFunction
45 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d;
46 | @end
47 |
48 | @interface GLDEasingFunctionOutQuart : GLDEasingFunction
49 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d;
50 | @end
51 |
52 | @interface GLDEasingFunctionInOutQuart: GLDEasingFunction
53 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d;
54 | @end
55 |
56 | @interface GLDEasingFunctionInQuint : GLDEasingFunction
57 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d;
58 | @end
59 |
60 | @interface GLDEasingFunctionOutQuint : GLDEasingFunction
61 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d;
62 | @end
63 |
64 | @interface GLDEasingFunctionInOutQuint: GLDEasingFunction
65 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d;
66 | @end
67 |
68 | @interface GLDEasingFunctionInSine : GLDEasingFunction
69 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d;
70 | @end
71 |
72 | @interface GLDEasingFunctionOutSine : GLDEasingFunction
73 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d;
74 | @end
75 |
76 | @interface GLDEasingFunctionInOutSine: GLDEasingFunction
77 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d;
78 | @end
79 |
80 | @interface GLDEasingFunctionInExpo : GLDEasingFunction
81 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d;
82 | @end
83 |
84 | @interface GLDEasingFunctionOutExpo : GLDEasingFunction
85 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d;
86 | @end
87 |
88 | @interface GLDEasingFunctionInOutExpo: GLDEasingFunction
89 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d;
90 | @end
91 |
92 | @interface GLDEasingFunctionInCirc : GLDEasingFunction
93 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d;
94 | @end
95 |
96 | @interface GLDEasingFunctionOutCirc : GLDEasingFunction
97 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d;
98 | @end
99 |
100 | @interface GLDEasingFunctionInOutCirc: GLDEasingFunction
101 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d;
102 | @end
103 |
104 | @interface GLDEasingFunctionInBack : GLDEasingFunction
105 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d;
106 | @end
107 |
108 | @interface GLDEasingFunctionOutBack : GLDEasingFunction
109 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d;
110 | @end
111 |
112 | @interface GLDEasingFunctionInOutBack: GLDEasingFunction
113 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d;
114 | @end
115 |
116 | @interface GLDEasingFunctionInBounce : GLDEasingFunction
117 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d;
118 | @end
119 |
120 | @interface GLDEasingFunctionOutBounce : GLDEasingFunction
121 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d;
122 | @end
123 |
124 | @interface GLDEasingFunctionInOutBounce: GLDEasingFunction
125 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d;
126 | @end
127 |
128 | @interface GLDEasingFunctionInElastic : GLDEasingFunction
129 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d;
130 | @end
131 |
132 | @interface GLDEasingFunctionOutElastic : GLDEasingFunction
133 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d;
134 | @end
135 |
136 | @interface GLDEasingFunctionInOutElastic: GLDEasingFunction
137 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d;
138 | @end
139 |
--------------------------------------------------------------------------------
/GLDTween/Plugins/GLDTweenPropertyPlugin.m:
--------------------------------------------------------------------------------
1 | //
2 | // GLDTweenPropertyPlugin.m
3 | // GLDTween
4 | //
5 | // Created by Takayuki Fukatsu on 2014/10/01.
6 | // Copyright (c) 2014 THE GUILD. All rights reserved.
7 | //
8 |
9 | #import "GLDTweenPropertyPlugin.h"
10 |
11 |
12 | @implementation GLDTweenPropertyX
13 | - (void)setValue:(NSValue *)value forTarget:(NSObject *)target key:(NSString *)key {
14 | if ([target isKindOfClass:[UIView class]] && [value isKindOfClass:[NSNumber class]]) {
15 | UIView *view = (UIView *)target;
16 | CGRect rect = view.frame;
17 | rect.origin = CGPointMake(((NSNumber *)value).floatValue, view.frame.origin.y);
18 | view.frame = rect;
19 | } else {
20 | [super setValue:value forTarget:target key:key];
21 | }
22 | }
23 |
24 | - (id)valueForTarget:(NSObject *)target key:(NSString *)key {
25 | if ([target isKindOfClass:[UIView class]]) {
26 | return [NSNumber numberWithFloat:((UIView *)target).frame.origin.x];
27 | }
28 | return [super valueForTarget:target key:key];
29 | }
30 | @end
31 |
32 |
33 | @implementation GLDTweenPropertyY
34 | - (void)setValue:(NSValue *)value forTarget:(NSObject *)target key:(NSString *)key {
35 | if ([target isKindOfClass:[UIView class]] && [value isKindOfClass:[NSNumber class]]) {
36 | UIView *view = (UIView *)target;
37 | CGRect rect = view.frame;
38 | rect.origin = CGPointMake(view.frame.origin.x, ((NSNumber *)value).floatValue);
39 | view.frame = rect;
40 | } else {
41 | [super setValue:value forTarget:target key:key];
42 | }
43 | }
44 |
45 | - (id)valueForTarget:(NSObject *)target key:(NSString *)key {
46 | if ([target isKindOfClass:[UIView class]]) {
47 | return [NSNumber numberWithFloat:((UIView *)target).frame.origin.x];
48 | }
49 | return [super valueForTarget:target key:key];
50 | }
51 | @end
52 |
53 |
54 | @implementation GLDTweenPropertyWidth
55 | - (void)setValue:(NSValue *)value forTarget:(NSObject *)target key:(NSString *)key {
56 | if ([target isKindOfClass:[UIView class]] && [value isKindOfClass:[NSNumber class]]) {
57 | UIView *view = (UIView *)target;
58 | CGRect rect = view.frame;
59 | rect.size = CGSizeMake(((NSNumber *)value).floatValue, view.frame.size.height);
60 | view.frame = rect;
61 | } else {
62 | [super setValue:value forTarget:target key:key];
63 | }
64 | }
65 |
66 | - (id)valueForTarget:(NSObject *)target key:(NSString *)key {
67 | if ([target isKindOfClass:[UIView class]]) {
68 | return [NSNumber numberWithFloat:((UIView *)target).frame.size.width];
69 | }
70 | return [super valueForTarget:target key:key];
71 | }
72 | @end
73 |
74 |
75 | @implementation GLDTweenPropertyHeight
76 | - (void)setValue:(NSValue *)value forTarget:(NSObject *)target key:(NSString *)key {
77 | if ([target isKindOfClass:[UIView class]] && [value isKindOfClass:[NSNumber class]]) {
78 | UIView *view = (UIView *)target;
79 | CGRect rect = view.frame;
80 | rect.size = CGSizeMake(view.frame.size.width, ((NSNumber *)value).floatValue);
81 | view.frame = rect;
82 | } else {
83 | [super setValue:value forTarget:target key:key];
84 | }
85 | }
86 |
87 | - (id)valueForTarget:(NSObject *)target key:(NSString *)key {
88 | if ([target isKindOfClass:[UIView class]]) {
89 | return [NSNumber numberWithFloat:((UIView *)target).frame.size.height];
90 | }
91 | return [super valueForTarget:target key:key];
92 | }
93 | @end
94 |
95 |
96 | /**
97 | Property Proxy for UIView.center.x
98 | */
99 | @implementation GLDTweenPropertyCenterX
100 | - (void)setValue:(NSValue *)value forTarget:(NSObject *)target key:(NSString *)key {
101 | if ([target isKindOfClass:[UIView class]] && [value isKindOfClass:[NSNumber class]]) {
102 | UIView *view = (UIView *)target;
103 | CGPoint pt = view.center;
104 | pt.x = ((NSNumber *)value).floatValue;
105 | view.center = pt;
106 | } else {
107 | [super setValue:value forTarget:target key:key];
108 | }
109 | }
110 |
111 | - (id)valueForTarget:(NSObject *)target key:(NSString *)key {
112 | if ([target isKindOfClass:[UIView class]]) {
113 | return [NSNumber numberWithFloat:((UIView *)target).center.x];
114 | }
115 | return [super valueForTarget:target key:key];
116 | }
117 | @end
118 |
119 |
120 | /**
121 | Property Proxy for UIView.center.y
122 | */
123 | @implementation GLDTweenPropertyCenterY
124 | - (void)setValue:(NSValue *)value forTarget:(NSObject *)target key:(NSString *)key {
125 | if ([target isKindOfClass:[UIView class]] && [value isKindOfClass:[NSNumber class]]) {
126 | UIView *view = (UIView *)target;
127 | CGPoint pt = view.center;
128 | pt.y = ((NSNumber *)value).floatValue;
129 | view.center = pt;
130 | } else {
131 | [super setValue:value forTarget:target key:key];
132 | }
133 | }
134 |
135 | - (id)valueForTarget:(NSObject *)target key:(NSString *)key {
136 | if ([target isKindOfClass:[UIView class]]) {
137 | return [NSNumber numberWithFloat:((UIView *)target).center.y];
138 | }
139 | return [super valueForTarget:target key:key];
140 | }
141 | @end
142 |
143 |
144 | /**
145 | Property Proxy for UIView.layer.transform3D
146 | */
147 | @implementation GLDTweenPropertyTransform3D
148 | - (void)setValue:(NSValue *)value forTarget:(NSObject *)target key:(NSString *)key {
149 | if ([target isKindOfClass:[UIView class]]) {
150 | ((UIView *)target).layer.transform = [value CATransform3DValue];
151 | } else {
152 | [super setValue:value forTarget:target key:key];
153 | }
154 | }
155 |
156 | - (id)valueForTarget:(NSObject *)target key:(NSString *)key {
157 | if ([target isKindOfClass:[UIView class]]) {
158 | return [NSValue valueWithCATransform3D:((UIView *)target).layer.transform];
159 | }
160 | return [super valueForTarget:target key:key];
161 | }
162 | @end
163 |
--------------------------------------------------------------------------------
/GLDTween/GLDTweenProperty.m:
--------------------------------------------------------------------------------
1 | //
2 | // GLDTweenProperty.m
3 | // GLDTween
4 | //
5 | // Created by Takayuki Fukatsu on 2014/10/01.
6 | // Copyright (c) 2014 THE GUILD. All rights reserved.
7 | //
8 |
9 | #import "GLDTweenProperty.h"
10 |
11 |
12 | @implementation GLDTweenProperty
13 |
14 |
15 | - (void)setValue:(id)value forTarget:(NSObject *)target key:(NSString *)key {
16 | [target setValue:value forKey:key];
17 | }
18 |
19 |
20 | - (id)valueForTarget:(NSObject *)target key:(NSString *)key {
21 | return [target valueForKey:key];
22 | }
23 |
24 |
25 | - (void)setStartValueForTarget:(NSObject *)target key:(NSString *)key {
26 | [target setValue:self.startValue forKey:key];
27 | }
28 |
29 |
30 | - (void)setTweenValueForTarget:(NSObject *)target key:(NSString *)key time:(float)t duration:(float)d ease:(GLDEasingFunction *)ease {
31 | }
32 |
33 |
34 | - (void)setCompleteValueForTarget:(NSObject *)target key:(NSString *)key {
35 | [self setValue:self.completeValue forTarget:target key:key];
36 | }
37 |
38 |
39 | - (void)updateStartValueForTarget:(NSObject *)target key:(NSString *)key {
40 | self.startValue = [self valueForTarget:target key:key];
41 | }
42 |
43 |
44 | @end
45 |
46 |
47 | //Property wrapper for Number
48 | @implementation GLDTweenPropertyCGFloat
49 |
50 |
51 | - (NSString *)type {
52 | return @"CGFloat";
53 | }
54 |
55 |
56 | - (void)setTweenValueForTarget:(NSObject *)target key:(NSString *)key time:(float)t duration:(float)d ease:(GLDEasingFunction *)ease {
57 | float b = ((NSNumber *)self.startValue).floatValue;
58 | float c = ((NSNumber *)self.completeValue).floatValue - b;
59 | float val = [ease t:t b:b c:c d:d];
60 | [self setValue:[NSNumber numberWithFloat:val] forTarget:target key:key];
61 | }
62 |
63 |
64 | @end
65 |
66 |
67 | //Property wrapper for CGPoint
68 | @implementation GLDTweenPropertyCGPoint
69 |
70 |
71 | - (NSString *)type {
72 | return @"CGPoint";
73 | }
74 |
75 |
76 | - (void)setTweenValueForTarget:(NSObject *)target key:(NSString *)key time:(float)t duration:(float)d ease:(GLDEasingFunction *)ease {
77 | CGPoint spt = self.startValue.CGPointValue;
78 | CGPoint cpt = self.completeValue.CGPointValue;
79 | CGPoint destPt = CGPointMake([ease t:t b:spt.x c:cpt.x - spt.x d:d],
80 | [ease t:t b:spt.y c:cpt.y - spt.y d:d]);
81 | [self setValue:[NSValue valueWithCGPoint:destPt] forTarget:target key:key];
82 | }
83 |
84 |
85 | @end
86 |
87 |
88 | //Property wrapper for CGSize
89 | @implementation GLDTweenPropertyCGSize
90 |
91 |
92 | - (NSString *)type {
93 | return @"CGSize";
94 | }
95 |
96 |
97 | - (void)setTweenValueForTarget:(NSObject *)target key:(NSString *)key time:(float)t duration:(float)d ease:(GLDEasingFunction *)ease {
98 | CGPoint ssz = self.startValue.CGPointValue;
99 | CGPoint csz = self.completeValue.CGPointValue;
100 | CGSize destSz = CGSizeMake([ease t:t b:ssz.x c:csz.x - ssz.x d:d],
101 | [ease t:t b:ssz.y c:csz.y - ssz.y d:d]);
102 | [self setValue:[NSValue valueWithCGSize:destSz] forTarget:target key:key];
103 | }
104 |
105 |
106 | @end
107 |
108 |
109 | //Property wrapper for CGRect
110 | @implementation GLDTweenPropertyCGRect
111 |
112 |
113 | - (NSString *)type {
114 | return @"CGRect";
115 | }
116 |
117 |
118 | - (void)setTweenValueForTarget:(NSObject *)target key:(NSString *)key time:(float)t duration:(float)d ease:(GLDEasingFunction *)ease {
119 | CGRect src = self.startValue.CGRectValue;
120 | CGRect crc = self.completeValue.CGRectValue;
121 | CGRect destRc = CGRectMake([ease t:t b:src.origin.x c:crc.origin.x - src.origin.x d:d],
122 | [ease t:t b:src.origin.y c:crc.origin.y - src.origin.y d:d],
123 | [ease t:t b:src.size.width c:crc.size.width - src.size.width d:d],
124 | [ease t:t b:src.size.height c:crc.size.height - src.size.height d:d]);
125 | [self setValue:[NSValue valueWithCGRect:destRc] forTarget:target key:key];
126 | }
127 |
128 |
129 | @end
130 |
131 |
132 | //Property wrapper for CGRect
133 | @implementation GLDTweenPropertyCGAffineTransform
134 |
135 |
136 | - (NSString *)type {
137 | return @"CGAffineTransform";
138 | }
139 |
140 |
141 | - (void)setTweenValueForTarget:(NSObject *)target key:(NSString *)key time:(float)t duration:(float)d ease:(GLDEasingFunction *)ease {
142 | CGAffineTransform sat = self.startValue.CGAffineTransformValue;
143 | CGAffineTransform cat = self.completeValue.CGAffineTransformValue;
144 | CGAffineTransform destAt = CGAffineTransformMake([ease t:t b:sat.a c:cat.a - sat.a d:d],
145 | [ease t:t b:sat.b c:cat.b - sat.b d:d],
146 | [ease t:t b:sat.c c:cat.c - sat.c d:d],
147 | [ease t:t b:sat.d c:cat.d - sat.d d:d],
148 | [ease t:t b:sat.tx c:cat.tx - sat.tx d:d],
149 | [ease t:t b:sat.ty c:cat.ty - sat.ty d:d]);
150 | [self setValue:[NSValue valueWithCGAffineTransform:destAt] forTarget:target key:key];
151 | }
152 |
153 |
154 | @end
155 |
156 |
157 | //Property wrapper for CGRect
158 | @implementation GLDTweenPropertyCATransform3D
159 |
160 |
161 | - (NSString *)type {
162 | return @"CATransform3D";
163 | }
164 |
165 |
166 | - (void)setTweenValueForTarget:(NSObject *)target key:(NSString *)key time:(float)t duration:(float)d ease:(GLDEasingFunction *)ease {
167 | CATransform3D st3 = self.startValue.CATransform3DValue;
168 | CATransform3D ct3 = self.completeValue.CATransform3DValue;
169 |
170 | CATransform3D destT3 = CATransform3DIdentity;
171 | destT3.m11 = [ease t:t b:st3.m11 c:ct3.m11 - st3.m11 d:d];
172 | destT3.m12 = [ease t:t b:st3.m12 c:ct3.m12 - st3.m12 d:d];
173 | destT3.m13 = [ease t:t b:st3.m13 c:ct3.m13 - st3.m13 d:d];
174 | destT3.m14 = [ease t:t b:st3.m14 c:ct3.m14 - st3.m14 d:d];
175 | destT3.m21 = [ease t:t b:st3.m21 c:ct3.m21 - st3.m21 d:d];
176 | destT3.m22 = [ease t:t b:st3.m22 c:ct3.m22 - st3.m22 d:d];
177 | destT3.m23 = [ease t:t b:st3.m23 c:ct3.m23 - st3.m23 d:d];
178 | destT3.m24 = [ease t:t b:st3.m24 c:ct3.m24 - st3.m24 d:d];
179 | destT3.m31 = [ease t:t b:st3.m31 c:ct3.m31 - st3.m31 d:d];
180 | destT3.m32 = [ease t:t b:st3.m32 c:ct3.m32 - st3.m32 d:d];
181 | destT3.m33 = [ease t:t b:st3.m33 c:ct3.m33 - st3.m33 d:d];
182 | destT3.m34 = [ease t:t b:st3.m34 c:ct3.m34 - st3.m34 d:d];
183 | destT3.m41 = [ease t:t b:st3.m41 c:ct3.m41 - st3.m41 d:d];
184 | destT3.m42 = [ease t:t b:st3.m42 c:ct3.m42 - st3.m42 d:d];
185 | destT3.m43 = [ease t:t b:st3.m43 c:ct3.m43 - st3.m43 d:d];
186 | destT3.m44 = [ease t:t b:st3.m44 c:ct3.m44 - st3.m44 d:d];
187 |
188 | [self setValue:[NSValue valueWithCATransform3D:destT3] forTarget:target key:key];
189 | }
190 |
191 |
192 | @end
193 |
--------------------------------------------------------------------------------
/GLDTween/Plugins/GLDEasingPlugin.m:
--------------------------------------------------------------------------------
1 | //
2 | // GLDEasingPlugin.m
3 | // GLDTween
4 | //
5 | // Created by Takayuki Fukatsu on 2014/10/01.
6 | // Copyright (c) 2014 THE GUILD. All rights reserved.
7 | //
8 |
9 | #import "GLDEasingPlugin.h"
10 |
11 |
12 | @implementation GLDEasingFunction
13 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d {
14 | return 0;
15 | }
16 | @end
17 |
18 |
19 | @implementation GLDEasingFunctionNone
20 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d {
21 | return c * t / d + b;
22 | }
23 | @end
24 |
25 |
26 | @implementation GLDEasingFunctionInQuad
27 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d {
28 | float t2 = t / d;
29 | return b + c * t2 * t2;
30 | }
31 | @end
32 |
33 |
34 | @implementation GLDEasingFunctionOutQuad
35 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d {
36 | float t2 = t / d;
37 | return b + (-c * t2 * (t2 - 2));
38 | }
39 | @end
40 |
41 |
42 | @implementation GLDEasingFunctionInOutQuad
43 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d {
44 | float t2 = t / d * 2;
45 | if (t2 < 1) {
46 | return c / 2 * t2 * t2 + b;
47 | }
48 | --t2;
49 | return - c / 2 * (t2 * (t2 - 2) - 1) + b;
50 | }
51 | @end
52 |
53 |
54 | @implementation GLDEasingFunctionInCubic
55 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d {
56 | float t2 = t / d;
57 | return b + c * t2 * t2 * t2;
58 | }
59 | @end
60 |
61 |
62 | @implementation GLDEasingFunctionOutCubic
63 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d {
64 | float t2 = t / d;
65 | --t2;
66 | return b + c * (t2 * t2 * t2 + 1);
67 | }
68 | @end
69 |
70 |
71 | @implementation GLDEasingFunctionInOutCubic
72 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d {
73 | float t2 = t / d * 2;
74 | if (t2 < 1) {
75 | return c / 2 * t2 * t2 * t2 + b;
76 | }
77 | t2 -= 2;
78 | return b + c / 2 * (t2 * t2 * t2 + 2);
79 | }
80 | @end
81 |
82 |
83 | @implementation GLDEasingFunctionInQuart
84 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d {
85 | float t2 = t / d;
86 | return b + c * t2 * t2 * t2 * t2;
87 | }
88 | @end
89 |
90 |
91 | @implementation GLDEasingFunctionOutQuart
92 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d {
93 | float t2 = t / d;
94 | --t2;
95 | return b - c * (t2 * t2 * t2 * t2 - 1);
96 | }
97 | @end
98 |
99 |
100 | @implementation GLDEasingFunctionInOutQuart
101 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d {
102 | float t2 = t / d * 2;
103 | if (t2 < 1) {
104 | return c / 2 * t2 * t2 * t2 * t2 + b;
105 | }
106 | t2 -= 2;
107 | return b - c / 2 * (t2 * t2 * t2 * t2 - 2);
108 | }
109 | @end
110 |
111 |
112 | @implementation GLDEasingFunctionInQuint
113 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d {
114 | float t2 = t / d;
115 | return b + c * t2 * t2 * t2 * t2 * t2;
116 | }
117 | @end
118 |
119 |
120 | @implementation GLDEasingFunctionOutQuint
121 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d {
122 | float t2 = t / d;
123 | --t2;
124 | return b + c * (t2 * t2 * t2 * t2 * t2 + 1);
125 | }
126 | @end
127 |
128 |
129 | @implementation GLDEasingFunctionInOutQuint
130 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d {
131 | float t2 = t / d * 2;
132 | if (t2 < 1) {
133 | return c / 2 * t2 * t2 * t2 * t2 * t2 + b;
134 | }
135 | t2 -= 2;
136 | return b + c / 2 * (t2 * t2 * t2 * t2 * t2 + 2);
137 | }
138 | @end
139 |
140 |
141 | @implementation GLDEasingFunctionInSine
142 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d {
143 | return -c * cosf(t / d * (M_PI_2)) + c + b;
144 | }
145 | @end
146 |
147 |
148 | @implementation GLDEasingFunctionOutSine
149 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d {
150 | return c * sinf(t / d * (M_PI_2)) + b;
151 | }
152 | @end
153 |
154 |
155 | @implementation GLDEasingFunctionInOutSine
156 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d {
157 | return -c / 2 * (cosf(M_PI * t / d) - 1) + b;
158 | }
159 | @end
160 |
161 |
162 | @implementation GLDEasingFunctionInExpo
163 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d {
164 | return c * powf(2.0f, 10 * (t / d - 1)) + b;
165 | }
166 | @end
167 |
168 |
169 | @implementation GLDEasingFunctionOutExpo
170 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d {
171 | return c * (-powf(2.0f, -10 * t / d) + 1) + b;
172 | }
173 | @end
174 |
175 |
176 | @implementation GLDEasingFunctionInOutExpo
177 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d {
178 | float t2 = t / d * 2;
179 | if (t2 < 1) {
180 | return c / 2 * powf(2.0f, 10 * (t2 - 1)) + b;
181 | }
182 | t2--;
183 | return c / 2 * (-powf(2.0f, -10 * t2) + 2) + b;
184 | }
185 | @end
186 |
187 |
188 | @implementation GLDEasingFunctionInCirc
189 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d {
190 | float t2 = t / d;
191 | return -c * (sqrtf(1 - t2 * t2) - 1) + b;
192 | }
193 | @end
194 |
195 |
196 | @implementation GLDEasingFunctionOutCirc
197 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d {
198 | float t2 = t / d;
199 | --t2;
200 | return c * sqrtf(1 - t2 * t2) + b;
201 | }
202 | @end
203 |
204 |
205 | @implementation GLDEasingFunctionInOutCirc
206 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d {
207 | float t2 = t / d * 2;
208 | if (t2 < 1) {
209 | return -c / 2 * (sqrtf(1 - t2 * t2) - 1) + b;
210 | }
211 | t2 -= 2;
212 | return c / 2 * (sqrtf(1 - t2 * t2) + 1) + b;
213 | }
214 | @end
215 |
216 |
217 | /*
218 | 暫定でfeb19の式からコピー
219 | https://github.com/feb19/Value-Tween-Library-for-Objective-C
220 | */
221 |
222 | @implementation GLDEasingFunctionInBack
223 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d {
224 | float s = 1.70158f;
225 | t /= d;
226 | return c * t * t * ((s + 1) * t - s) + b;
227 | }
228 | @end
229 |
230 |
231 | @implementation GLDEasingFunctionOutBack
232 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d {
233 | float s = 1.70158f;
234 | t = t / d - 1;
235 | return c * (t * t * ((s + 1) * t + s) + 1) + b;
236 | }
237 | @end
238 |
239 |
240 | @implementation GLDEasingFunctionInOutBack
241 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d {
242 | float s = 1.70158f;
243 | float k = 1.525f;
244 | t /= d / 2;
245 | s *= k;
246 | if (t < 1) {
247 | return c / 2 * (t * t * ((s + 1) * t - s)) + b;
248 | } else {
249 | t -= 2;
250 | return c / 2 * (t * t * ((s + 1) * t + s) + 2) + b;
251 | }
252 | }
253 | @end
254 |
255 |
256 | // TODO: optimize
257 | @implementation GLDEasingFunctionInBounce
258 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d {
259 | //return c - easeOutBounce (d - t, 0, c, d) + b;
260 | float val = 0;
261 | float t2 = d - t;
262 | //from easeOutBounce
263 | t2 /= d;
264 | if (t2 < (1 / 2.75f)) {
265 | val = c * (7.5625f * t2 * t2);
266 | } else if (t < (2 / 2.75f)) {
267 | t2 -= (1.5f / 2.75f);
268 | val = c * (7.5625f * t2 * t2 + 0.75f);
269 | } else if (t < (2.5f / 2.75f)) {
270 | t2 -= (2.25f / 2.75f);
271 | val = c * (7.5625f * t2 * t2 + 0.9375f);
272 | } else {
273 | t2 -= (2.625f / 2.75f);
274 | val = c * (7.5625f * t2 * t2 + 0.984375f);
275 | }
276 |
277 | return c - val + b;
278 | }
279 | @end
280 |
281 |
282 | @implementation GLDEasingFunctionOutBounce
283 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d {
284 | t /= d;
285 | if (t < (1 / 2.75f)) {
286 | return c * (7.5625f * t * t) + b;
287 | } else if (t < (2 / 2.75f)) {
288 | t -= (1.5f / 2.75f);
289 | return c * (7.5625f * t * t + 0.75f) + b;
290 | } else if (t < (2.5f / 2.75f)) {
291 | t -= (2.25f / 2.75f);
292 | return c * (7.5625f * t * t + 0.9375f) + b;
293 | } else {
294 | t -= (2.625f / 2.75f);
295 | return c * (7.5625f * t * t + 0.984375f) + b;
296 | }
297 | }
298 | @end
299 |
300 |
301 | // TODO: optimize
302 | @implementation GLDEasingFunctionInOutBounce
303 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d {
304 | if (t < d / 2) {
305 | return [self inT:t * 2 b:0 c:c d:d] * 0.5f + b;
306 | } else {
307 | return [self outT:t * 2 - d b:0 c:c d:d] * 0.5f + c * 0.5f + b;
308 | }
309 | }
310 |
311 | - (float)inT:(float)t b:(float)b c:(float)c d:(float)d {
312 | return c - [self outT:d - t b:0 c:c d:d] + b;
313 | }
314 |
315 | - (float)outT:(float)t b:(float)b c:(float)c d:(float)d {
316 | t /= d;
317 | if (t < (1 / 2.75f)) {
318 | return c * (7.5625f * t * t) + b;
319 | } else if (t < (2 / 2.75f)) {
320 | t -= (1.5f / 2.75f);
321 | return c * (7.5625f * t * t + 0.75f) + b;
322 | } else if (t < (2.5f / 2.75f)) {
323 | t -= (2.25f / 2.75f);
324 | return c * (7.5625f * t * t + 0.9375f) + b;
325 | } else {
326 | t -= (2.625f / 2.75f);
327 | return c * (7.5625f * t * t + 0.984375f) + b;
328 | }
329 | }
330 | @end
331 |
332 |
333 | @implementation GLDEasingFunctionInElastic
334 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d {
335 | float s = 1.70158f;
336 | float p = 0;
337 | float a = c;
338 | if (t == 0) return b;
339 | if ((t /= d) == 1) return b+c;
340 | if (!p) p = d * 0.3f;
341 | if (a < fabsf(c)) {
342 | a = c;
343 | s = p / 4;
344 | } else {
345 | s = p / (2 * 3.1419f) * asinf(c / a);
346 | }
347 | --t;
348 | return -(a * powf(2, 10 * t) * sinf((t * d - s) * (2 * 3.1419f) / p)) + b;
349 | }
350 | @end
351 |
352 |
353 | @implementation GLDEasingFunctionOutElastic
354 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d {
355 | float s = 1.70158f;
356 | float p = 0;
357 | float a = c;
358 | if (t == 0) return b;
359 | if ((t /= d) == 1) return b + c;
360 | if (!p) p = d * 0.3f;
361 | if (a < fabsf(c)) {
362 | a = c;
363 | s = p / 4;
364 | } else {
365 | s = p / (2 * 3.1419f) * asinf(c / a);
366 | };
367 | return a * powf(2.0f, -10 * t) * sinf((t * d - s) * (2 * 3.1419f) / p) + c + b;
368 | }
369 | @end
370 |
371 |
372 | @implementation GLDEasingFunctionInOutElastic
373 | - (float)t:(float)t b:(float)b c:(float)c d:(float)d {
374 | float s = 1.70158f;
375 | float p = 0;
376 | float a = c;
377 | if (t == 0) return b;
378 | if ((t /= d / 2) == 2) return b + c;
379 | if (!p) p = d * (0.3f * 1.5f);
380 | if (a < fabsf(c)) {
381 | a = c;
382 | s = p / 4;
383 | } else {
384 | s = p / (2 * 3.1419f) * asinf(c / a);
385 | }
386 | if (t < 1) {
387 | --t;
388 | return -0.5 * (a * powf(2.0f, 10 * t) * sinf((t * d - s) * (2 * 3.1419f) / p)) + b;
389 | }
390 | --t;
391 | return a * powf(2.0f, -10 * t) * sinf((t * d - s) * (2 * 3.1419f) / p) * 0.5f + c + b;
392 | }
393 | @end
394 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | GLDTween
2 | ========
3 | GLDTween is a powerful animation library for iOS. It enables you to write complex animation with simple coding.
4 |
5 | GLDTweenはiOS用のハンディなアニメーション用ライブラリです。高度なアニメーションを、シンプルかつパワフルに記述できます。
6 |
7 |
8 |
9 |
10 | 作成の背景
11 | ----------
12 | iOSでは「手触り」が重要視されながらも、アニメーションに関するプログラミング資産は不足していました。UIAnimationはAppleの要求するアニメーション品質を実現するにはあまりに貧弱です。一方でCoreAnimationは強力なものの複雑でした。結局のところ、どちらも直感的に表現をコーディングするには向きません。
13 |
14 | GLDTweenはこの問題を解決するために開発されました。アニメーションの表現と技術で多くの蓄積があったFlashのノウハウをベースに、ActionScriptの伝説的アニメーションエンジン[Tweener](https://code.google.com/p/tweener/)をベースに設計されました。シンプルなAPIでパワフルな表現を実現します。
15 |
16 |
17 |
18 |
19 | GLDTweenの特徴
20 | --------------
21 | ##### シンプルな記法
22 | 大抵のアニメーションを1行で記述できます。型変換はライブラリが自動で行うので、CGPointやCATransform3Dなど様々な型を横断する必要がありません。
23 |
24 |
25 | ##### 競合への冗長性
26 | たとえばオブジェクトをアニメーション中に、さらに別のアニメーションを行った場合、GLDTweenは自動で同じプロパティのマージや上書きを行い競合や衝突を防ぎます。
27 |
28 |
29 | ##### 何でもアニメーションできる
30 | GLDTweenのサポートする一般的な数値型であれば、あらゆるプロパティがアニメーション可能です。数値型でさえあれば音楽のボリュームや、ビデオの再生位置すらアニメーション可能です!
31 |
32 |
33 | ##### 高い拡張性
34 | プラグイン方式を採用しているため、ライブラリそのものに手をいれずに独自のカスタマイズができます。アニメーション関数や、特殊な計算を行うプロパティを自分追加できます。
35 |
36 |
37 | ##### UIや画面の遷移に特化
38 | 数個〜数十個のUI要素や画面遷移を行うためのライブラリです。パーティクルのような万単位で同時に動かすアニメには向いていません。
39 |
40 |
41 |
42 |
43 | インストール
44 | ------------
45 | ##### CocoaPods
46 | [CocoaPods](http://cocoapods.org/)を使っている場合、以下をPodfileに追加します。
47 |
48 | ```ruby
49 | pod 'GLDTween', '~> 0.0.1'
50 | ```
51 |
52 |
53 | ##### GitあるいはZip
54 | 通常通りダウンロードやPushでインストールしてください。
55 | ライブラリの依存性としてはQuartzCore.frameworkが必要となります。
56 |
57 | 例えば、viewの移動をする場合、以下のように1行で書けます。
58 |
59 |
60 |
61 |
62 | サンプルコード
63 | --------------
64 | GLDTweenでは任意のNSObjectに対し、NSDictionaryでプロパティのアニメーションを指定します。
65 | NSValueを用いてラップをすることで、CGPoint、CGSize、CGRect、CGAffineTransformなどのプロパティも指定可能です。
66 |
67 |
68 | ### アニメーションを開始
69 | UIViewを座標(200, 300)に2秒で移動させます。
70 |
71 | ```
72 | [GLDTween addTween:myView
73 | params:@{@"duration": @2.0, // 時間
74 | @"delay": @0.0,
75 | @"easing": GLDEasingInOutExpo, // 任意のアニメーションカーブ
76 | @"center": [NSValue valueWithCGPoint:CGPointMake(200, 300)]
77 | }];
78 | ```
79 |
80 |
81 | あるいは標準プラグインの力で、CGPointのかわりにcenterX、centerYでも指定できます。
82 |
83 | ```
84 | [GLDTween addTween:myView
85 | params:@{@"duration": @2.0, // 時間
86 | @"delay": @0.0,
87 | @"easing": GLDEasingInOutExpo, // 任意のアニメーションカーブ
88 | @"centerX": @200, // center.xのショートカット
89 | @"centerY": @300, // center.yのショートカット
90 | }];
91 | ```
92 |
93 |
94 | ### アニメーションの削除
95 | 実行中の任意のNSObjectのアニメーションを削除します。
96 |
97 | ```
98 | [GLDTween removeTween:myView];
99 | ```
100 |
101 | あるいは特定のプロパティのアニメーションだけ削除することも可能です。
102 |
103 | ```
104 | [GLDTween removeTween:myView params:@[@"x", @"width"]];
105 | ```
106 |
107 |
108 | ##### 全てを削除する場合
109 |
110 | ```
111 | [GLDTween removeAllTweens];
112 | ```
113 |
114 |
115 | ##### アニメーションの一次停止と再開除
116 | 実行中のアニメーションを一時停止します。
117 |
118 | ```
119 | [GLDTween pauseTween:myView];
120 | ```
121 |
122 |
123 | ##### 一時停止中のアニメーションの再開
124 |
125 | ```
126 | [GLDTween resumeTween:myView];
127 | ```
128 |
129 |
130 | ##### 全てを一時停止
131 |
132 | ```
133 | [GLDTween pauseAllTweens];
134 | ```
135 |
136 |
137 | ##### 全ての一時停止を再開
138 |
139 | ```
140 | [GLDTween resumeAllTweens];
141 | ```
142 |
143 |
144 |
145 |
146 | ### 複数のアニメーション
147 | ##### 複数のプロパティを同時に指定
148 |
149 | ```
150 | [GLDTween addTween:myView
151 | params:@{@"duration": @2.0, // 時間
152 | @"delay": @0.0,
153 | @"easing": GLDEasingInOutExpo, // 任意のアニメーションカーブ
154 | @"width": @100,
155 | @"height": @100,
156 | @"centerX": @200,
157 | @"centerY": @300,
158 | @"alpha": @0.0
159 | }];
160 | ```
161 |
162 |
163 | ##### 複数のオブジェクトに同じ動きをさせる。
164 | パラメータの辞書を再利用することで、同じアニメーションを複数のNSObjectに適用できます。
165 |
166 | ```
167 | [GLDTween addTween:myView0 params:myDict];
168 | [GLDTween addTween:myView1 params:myDict];
169 | [GLDTween addTween:myView2 params:myDict];
170 | ```
171 |
172 |
173 | ##### 連続でアニメーション
174 | 右に1秒移動してから下に1秒移動する。
175 | 2つのアニメーションと、delayのパラメータ指定で連続的なアニメーションも記述できる。
176 |
177 | ```
178 | // 右に移動
179 | [GLDTween addTween:myView
180 | params:@{@"duration": @1.0, // 時間
181 | @"delay": @0.0,
182 | @"easing": GLDEasingInOutExpo,
183 | @"centerX": @200,
184 | }];
185 | // 下に移動
186 | [GLDTween addTween:myView
187 | params:@{@"duration": @1.0, // 時間
188 | @"delay": @1.0, // 1.0秒遅延させて実行
189 | @"easing": GLDEasingInOutExpo,
190 | @"centerY": @300,
191 | }];
192 | ```
193 |
194 |
195 | ### アニメーションの上書き、競合
196 | 同じ時間帯にアニメーションが競合する場合、2つ目のアニメーションへ自動で上書きされます。
197 | 下記の2つのアニメーションではXが競合するので、Xのみ2番目のアニメーションが優先されます。
198 |
199 | ```
200 | [GLDTween addTween:myView
201 | params:@{@"duration": @3.0, // 時間
202 | @"delay": @0.0,
203 | @"easing": GLDEasingInOutExpo,
204 | @"x": @200,
205 | @"y": @100,
206 | }];
207 | [GLDTween addTween:myView
208 | params:@{@"duration": @1.5, // 時間
209 | @"delay": @1.0,
210 | @"easing": GLDEasingInOutExpo,
211 | @"x": @300,
212 | }];
213 | ```
214 |
215 |
216 | ### アニメ開始時、終了時に特殊な処理を行う
217 | ブロックあるいはセレクターで、イベントハンドリングが可能。ただしNSDictionaryに格納するためにGLDTweenBlockあるいは、GLDTweenSelectorでラップする必要がある。
218 |
219 |
220 | ##### クロージャによるイベント処理
221 |
222 | ```
223 | __weak id s = self;
224 | [GLDTween addTween:myView
225 | params:@{@"duration": @1.0, // 時間
226 | @"delay": @0.0,
227 | @"easing": GLDEasingInOutExpo,
228 | @"startBlock": [GLDTweenBlock block:^(void){
229 | [s animationDidStart:nil]; // ブロック
230 | }],
231 | @"completionBlock": [GLDTweenBlock block:^(void){
232 | [s animationDidComplete:nil]; // ブロック
233 | }]
234 | }];
235 | ```
236 |
237 |
238 | ##### セレクターによるイベント処理
239 |
240 | ```
241 | [GLDTween addTween:myView
242 | params:@{@"duration": @1.0, // 時間
243 | @"delay": @0.0,
244 | @"easing": GLDEasingInOutExpo,
245 | @"startSelector": [GLDTweenSelector selector:@selector(animationDidStart:) withTarget:self],
246 | @"completionSelector": [GLDTweenSelector selector:@selector(animationDidComplete:) withTarget:self]
247 | }];
248 | ```
249 |
250 |
251 | ### アニメーション中の操作ロック
252 | locksInteraction、unlocksInteractionパラメータで、アニメーション中のユーザー操作をロックできます。
253 |
254 | ```
255 | [GLDTween addTween:myView
256 | params:@{@"duration": @1.0, // 時間
257 | @"delay": @0.0,
258 | @"easing": GLDEasingInOutExpo,
259 | @"locksInteraction": @YES, // 追加時に操作系をロック
260 | @"unlocksInteraction": @YES // 完了 or 削除時に操作系をアンロック
261 | }];
262 | ```
263 |
264 |
265 |
266 |
267 | 指定可能なパラメータ
268 | --------------------
269 | アニメーションのパラメータは、GLDTween.addTweenの第2引数で指定します。第2引数はNSDictionaryで、あらゆるデータ型を内包可能です。
270 |
271 |
272 | - duration: NSNumber
273 | - アニメーションの再生時間(秒)
274 | - delay: NSNumber
275 | - アニメーション開始までの遅延(秒)
276 | - transition: NSString
277 | - イージングカーブ(後述)の指定
278 | - repeat: NSNumber
279 | - 繰り返し回数。ディフォルトは0。-1を指定した場合は無限ループ。
280 | - locksInteraction: BOOL
281 | - アニメーション登録時にユーザーインタラクション(タッチ等)をロック。
282 | - unlocksInteraction: BOOL
283 | - アニメーション完了/削除時に、ユーザーインタラクション(タッチ等)をアンロック。
284 | - x: NSNumber
285 | - frame.origin.xの省略記法
286 | - y: NSNumber
287 | - frame.origin.yの省略記法
288 | - width: NSNumber
289 | - frame.size.widthの省略記法
290 | - height: NSNumber
291 | - frame.size.heightの省略記法
292 | - frame: CGRect
293 |
294 | - origin: CGPoint
295 |
296 | - size: CGSize
297 | - center: CGPoint
298 | - centerX: NSNumber
299 | - centerY: NSNumber
300 | - startBlock: GLDTweenBlock
301 | - アニメーション開始時に実行されるブロック。GLDTweenBlockでラップすること。
302 | - completionBlock: GLDTweenBlock
303 | - アニメーション開始時に実行されるブロック。GLDTweenBlockでラップすること。
304 | - updateBlock: GLDTweenBlock
305 | - アニメーション終了時に実行されるブロック。GLDTweenBlockでラップすること。
306 | - repeatBlock: GLDTweenBlock
307 | - アニメーション終了時に実行されるブロック。GLDTweenBlockでラップすること。
308 | - startSelector: GLDTweenSelector
309 | - アニメーション開始時に実行されるセレクター。GLDTweenSelectorでラップすること。
310 | - completionSelector: GLDTweenSelector
311 | - アニメーション更新時に実行されるセレクター。GLDTweenSelectorでラップすること。
312 | - updateSelector: GLDTweenSelector
313 | - アニメーションリピート時に実行されるセレクター。GLDTweenSelectorでラップすること。
314 | - repeatSelector: GLDTweenSelector
315 | - アニメーション終了時に実行されるセレクター。GLDTweenSelectorでラップすること。
316 | - その他
317 | - CGFloat、CGPoint、CGSize、CGRect、CGAffineTransform、CATransform3D型のプロパティはそのまま指定可能(例えばalpha等)。
318 |
319 |
320 |
321 |
322 |
323 | 対応プロパティ・データタイプ
324 | ----------------------------
325 | アニメーション対象として指定したNSObjectサブクラスから、valueForKeyで取得できる下記型のプロパティに対応しています。またNSObjectを拡張した場合、これらの型の値を返す全てのGetter/Setterもアニメーション可能です。
326 |
327 |
328 | - CGFloat
329 | - UIView.alpha等
330 | - CGPoint
331 | - UIView.center、CALayer.position等
332 | - CGSize
333 | - UIScrollView.contentSize等
334 | - CGRect
335 | - UIView.frame等
336 | - CGAffineTransform
337 | - UIView.transform等
338 | - CATranform3D
339 | - CALayer.transform等
340 | - UIColor(対応予定)
341 | - UIView.backgroundColor等
342 |
343 |
344 |
345 |
346 |
347 | 指定可能なアニメーションカーブ
348 | ------------------------------
349 | いわゆるRobert Pennerによる[主要アニメーションカーブ](http://easings.net/en)は全てサポートしています。
350 |
351 |
352 | - GLDEasingNone
353 | - GLDEasingInSine
354 | - GLDEasingOutSine
355 | - GLDEasingInOutSine
356 | - GLDEasingInQuad
357 | - GLDEasingOutQuad
358 | - GLDEasingInOutQuad
359 | - GLDEasingInCubic
360 | - GLDEasingOutCubic
361 | - GLDEasingInOutCubic
362 |
363 |
364 |
365 |
366 |
367 | プラグインの作成
368 | ----------------
369 | GLDTweenでは以下の2種類のプラグインを作成可能です。
370 | プラグインの作成方法は後述します。
371 |
372 |
373 | - アニメーション・カーブ
374 | - GLDEasingFunctionテンプレートクラスを継承することで、自身で定義したオリジナルのアニメーションカーブを登録できます。
375 | - 独自プロパティ
376 | - GLDSpecialPropertyを継承したアダプタクラスを作ることで、GLDTweenプリセットの対応プロパティだけでなく、様々なプロパティに対応可能です。
377 |
378 |
379 |
380 |
381 |
382 | 対応予定機能
383 | ------------
384 | - オートリバース
385 |
386 |
387 |
388 |
389 | TODO
390 | ----
391 | - コントリビュータを集める
392 | - サンプルコードを作る
393 | - TestCaseを書く
394 |
395 |
396 |
397 |
398 | Known Issues
399 | ------------
400 | - Swiftから使用する場合、GLDTweenSelectorによるコールバックが正常に作動しません。現段階ではGLDTweenBlockを使用してください。
401 |
--------------------------------------------------------------------------------
/Demo/GLDTween.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 3D5366F519DC31D10017C6B8 /* GLDTweenSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D5366F419DC31D10017C6B8 /* GLDTweenSelector.m */; };
11 | 3D5366F819DC337F0017C6B8 /* GLDTweenBlock.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D5366F719DC337F0017C6B8 /* GLDTweenBlock.m */; };
12 | 3D53670C19DE16270017C6B8 /* TouchDemoViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D53670B19DE16270017C6B8 /* TouchDemoViewController.m */; };
13 | 3D53675419DEE4550017C6B8 /* GLDEasingPlugin.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D53675119DEE4550017C6B8 /* GLDEasingPlugin.m */; };
14 | 3D53675519DEE4550017C6B8 /* GLDTweenPropertyPlugin.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D53675319DEE4550017C6B8 /* GLDTweenPropertyPlugin.m */; };
15 | 3DAE9D1F19DB9D30003692A1 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DAE9D1E19DB9D30003692A1 /* main.m */; };
16 | 3DAE9D2219DB9D30003692A1 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DAE9D2119DB9D30003692A1 /* AppDelegate.m */; };
17 | 3DAE9D2819DB9D30003692A1 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3DAE9D2619DB9D30003692A1 /* Main.storyboard */; };
18 | 3DAE9D2A19DB9D30003692A1 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3DAE9D2919DB9D30003692A1 /* Images.xcassets */; };
19 | 3DAE9D2D19DB9D30003692A1 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3DAE9D2B19DB9D30003692A1 /* LaunchScreen.xib */; };
20 | 3DAE9D3919DB9D30003692A1 /* GLDTweenTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DAE9D3819DB9D30003692A1 /* GLDTweenTests.m */; };
21 | 3DAE9D4519DB9DA0003692A1 /* GLDTween.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DAE9D4419DB9DA0003692A1 /* GLDTween.m */; };
22 | 3DAE9D4D19DBB3C9003692A1 /* GLDTweenProperty.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DAE9D4C19DBB3C9003692A1 /* GLDTweenProperty.m */; };
23 | 3DAE9D5319DBB5EE003692A1 /* GLDTweenTween.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DAE9D5219DBB5EE003692A1 /* GLDTweenTween.m */; };
24 | /* End PBXBuildFile section */
25 |
26 | /* Begin PBXContainerItemProxy section */
27 | 3DAE9D3319DB9D30003692A1 /* PBXContainerItemProxy */ = {
28 | isa = PBXContainerItemProxy;
29 | containerPortal = 3DAE9D1119DB9D30003692A1 /* Project object */;
30 | proxyType = 1;
31 | remoteGlobalIDString = 3DAE9D1819DB9D30003692A1;
32 | remoteInfo = GLDTween;
33 | };
34 | /* End PBXContainerItemProxy section */
35 |
36 | /* Begin PBXFileReference section */
37 | 3D5366F319DC31D10017C6B8 /* GLDTweenSelector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = GLDTweenSelector.h; path = ../../GLDTween/GLDTweenSelector.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
38 | 3D5366F419DC31D10017C6B8 /* GLDTweenSelector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; name = GLDTweenSelector.m; path = ../../GLDTween/GLDTweenSelector.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
39 | 3D5366F619DC337F0017C6B8 /* GLDTweenBlock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = GLDTweenBlock.h; path = ../../GLDTween/GLDTweenBlock.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
40 | 3D5366F719DC337F0017C6B8 /* GLDTweenBlock.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; name = GLDTweenBlock.m; path = ../../GLDTween/GLDTweenBlock.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
41 | 3D53670A19DE16270017C6B8 /* TouchDemoViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = TouchDemoViewController.h; path = TouchDemo/TouchDemoViewController.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
42 | 3D53670B19DE16270017C6B8 /* TouchDemoViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; name = TouchDemoViewController.m; path = TouchDemo/TouchDemoViewController.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
43 | 3D53675019DEE4550017C6B8 /* GLDEasingPlugin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = GLDEasingPlugin.h; path = ../../GLDTween/Plugins/GLDEasingPlugin.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
44 | 3D53675119DEE4550017C6B8 /* GLDEasingPlugin.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; name = GLDEasingPlugin.m; path = ../../GLDTween/Plugins/GLDEasingPlugin.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
45 | 3D53675219DEE4550017C6B8 /* GLDTweenPropertyPlugin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = GLDTweenPropertyPlugin.h; path = ../../GLDTween/Plugins/GLDTweenPropertyPlugin.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
46 | 3D53675319DEE4550017C6B8 /* GLDTweenPropertyPlugin.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; name = GLDTweenPropertyPlugin.m; path = ../../GLDTween/Plugins/GLDTweenPropertyPlugin.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
47 | 3DAE9D1919DB9D30003692A1 /* GLDTween.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GLDTween.app; sourceTree = BUILT_PRODUCTS_DIR; };
48 | 3DAE9D1D19DB9D30003692A1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
49 | 3DAE9D1E19DB9D30003692A1 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = main.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
50 | 3DAE9D2019DB9D30003692A1 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = AppDelegate.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
51 | 3DAE9D2119DB9D30003692A1 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = AppDelegate.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
52 | 3DAE9D2719DB9D30003692A1 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
53 | 3DAE9D2919DB9D30003692A1 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; };
54 | 3DAE9D2C19DB9D30003692A1 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; };
55 | 3DAE9D3219DB9D30003692A1 /* GLDTweenTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = GLDTweenTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
56 | 3DAE9D3719DB9D30003692A1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
57 | 3DAE9D3819DB9D30003692A1 /* GLDTweenTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = GLDTweenTests.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
58 | 3DAE9D4319DB9DA0003692A1 /* GLDTween.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = GLDTween.h; path = ../../GLDTween/GLDTween.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
59 | 3DAE9D4419DB9DA0003692A1 /* GLDTween.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; name = GLDTween.m; path = ../../GLDTween/GLDTween.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
60 | 3DAE9D4B19DBB3C9003692A1 /* GLDTweenProperty.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = GLDTweenProperty.h; path = ../../GLDTween/GLDTweenProperty.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
61 | 3DAE9D4C19DBB3C9003692A1 /* GLDTweenProperty.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; name = GLDTweenProperty.m; path = ../../GLDTween/GLDTweenProperty.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
62 | 3DAE9D5119DBB5EE003692A1 /* GLDTweenTween.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = GLDTweenTween.h; path = ../../GLDTween/GLDTweenTween.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
63 | 3DAE9D5219DBB5EE003692A1 /* GLDTweenTween.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; name = GLDTweenTween.m; path = ../../GLDTween/GLDTweenTween.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
64 | /* End PBXFileReference section */
65 |
66 | /* Begin PBXFrameworksBuildPhase section */
67 | 3DAE9D1619DB9D30003692A1 /* Frameworks */ = {
68 | isa = PBXFrameworksBuildPhase;
69 | buildActionMask = 2147483647;
70 | files = (
71 | );
72 | runOnlyForDeploymentPostprocessing = 0;
73 | };
74 | 3DAE9D2F19DB9D30003692A1 /* Frameworks */ = {
75 | isa = PBXFrameworksBuildPhase;
76 | buildActionMask = 2147483647;
77 | files = (
78 | );
79 | runOnlyForDeploymentPostprocessing = 0;
80 | };
81 | /* End PBXFrameworksBuildPhase section */
82 |
83 | /* Begin PBXGroup section */
84 | 3D53670219DD57610017C6B8 /* Sample */ = {
85 | isa = PBXGroup;
86 | children = (
87 | 3D53670919DE160D0017C6B8 /* TouchDemo */,
88 | );
89 | name = Sample;
90 | sourceTree = "";
91 | };
92 | 3D53670919DE160D0017C6B8 /* TouchDemo */ = {
93 | isa = PBXGroup;
94 | children = (
95 | 3D53670A19DE16270017C6B8 /* TouchDemoViewController.h */,
96 | 3D53670B19DE16270017C6B8 /* TouchDemoViewController.m */,
97 | );
98 | name = TouchDemo;
99 | sourceTree = "";
100 | };
101 | 3DAE9D1019DB9D30003692A1 = {
102 | isa = PBXGroup;
103 | children = (
104 | 3DAE9D1B19DB9D30003692A1 /* GLDTween */,
105 | 3DAE9D3519DB9D30003692A1 /* GLDTweenTests */,
106 | 3DAE9D1A19DB9D30003692A1 /* Products */,
107 | );
108 | sourceTree = "";
109 | };
110 | 3DAE9D1A19DB9D30003692A1 /* Products */ = {
111 | isa = PBXGroup;
112 | children = (
113 | 3DAE9D1919DB9D30003692A1 /* GLDTween.app */,
114 | 3DAE9D3219DB9D30003692A1 /* GLDTweenTests.xctest */,
115 | );
116 | name = Products;
117 | sourceTree = "";
118 | };
119 | 3DAE9D1B19DB9D30003692A1 /* GLDTween */ = {
120 | isa = PBXGroup;
121 | children = (
122 | 3DAE9D4219DB9D8B003692A1 /* GLDTween */,
123 | 3D53670219DD57610017C6B8 /* Sample */,
124 | 3DAE9D2019DB9D30003692A1 /* AppDelegate.h */,
125 | 3DAE9D2119DB9D30003692A1 /* AppDelegate.m */,
126 | 3DAE9D2619DB9D30003692A1 /* Main.storyboard */,
127 | 3DAE9D2919DB9D30003692A1 /* Images.xcassets */,
128 | 3DAE9D2B19DB9D30003692A1 /* LaunchScreen.xib */,
129 | 3DAE9D1C19DB9D30003692A1 /* Supporting Files */,
130 | );
131 | path = GLDTween;
132 | sourceTree = "";
133 | };
134 | 3DAE9D1C19DB9D30003692A1 /* Supporting Files */ = {
135 | isa = PBXGroup;
136 | children = (
137 | 3DAE9D1D19DB9D30003692A1 /* Info.plist */,
138 | 3DAE9D1E19DB9D30003692A1 /* main.m */,
139 | );
140 | name = "Supporting Files";
141 | sourceTree = "";
142 | };
143 | 3DAE9D3519DB9D30003692A1 /* GLDTweenTests */ = {
144 | isa = PBXGroup;
145 | children = (
146 | 3DAE9D3819DB9D30003692A1 /* GLDTweenTests.m */,
147 | 3DAE9D3619DB9D30003692A1 /* Supporting Files */,
148 | );
149 | path = GLDTweenTests;
150 | sourceTree = "";
151 | };
152 | 3DAE9D3619DB9D30003692A1 /* Supporting Files */ = {
153 | isa = PBXGroup;
154 | children = (
155 | 3DAE9D3719DB9D30003692A1 /* Info.plist */,
156 | );
157 | name = "Supporting Files";
158 | sourceTree = "";
159 | };
160 | 3DAE9D4219DB9D8B003692A1 /* GLDTween */ = {
161 | isa = PBXGroup;
162 | children = (
163 | 3DAE9D4319DB9DA0003692A1 /* GLDTween.h */,
164 | 3DAE9D4419DB9DA0003692A1 /* GLDTween.m */,
165 | 3DAE9D4A19DBA6D4003692A1 /* core */,
166 | 3DAE9D4919DBA11D003692A1 /* plugins */,
167 | );
168 | name = GLDTween;
169 | sourceTree = "";
170 | };
171 | 3DAE9D4919DBA11D003692A1 /* plugins */ = {
172 | isa = PBXGroup;
173 | children = (
174 | 3D53675019DEE4550017C6B8 /* GLDEasingPlugin.h */,
175 | 3D53675119DEE4550017C6B8 /* GLDEasingPlugin.m */,
176 | 3D53675219DEE4550017C6B8 /* GLDTweenPropertyPlugin.h */,
177 | 3D53675319DEE4550017C6B8 /* GLDTweenPropertyPlugin.m */,
178 | );
179 | name = plugins;
180 | sourceTree = "";
181 | };
182 | 3DAE9D4A19DBA6D4003692A1 /* core */ = {
183 | isa = PBXGroup;
184 | children = (
185 | 3DAE9D5119DBB5EE003692A1 /* GLDTweenTween.h */,
186 | 3DAE9D5219DBB5EE003692A1 /* GLDTweenTween.m */,
187 | 3DAE9D4B19DBB3C9003692A1 /* GLDTweenProperty.h */,
188 | 3DAE9D4C19DBB3C9003692A1 /* GLDTweenProperty.m */,
189 | 3D5366F319DC31D10017C6B8 /* GLDTweenSelector.h */,
190 | 3D5366F419DC31D10017C6B8 /* GLDTweenSelector.m */,
191 | 3D5366F619DC337F0017C6B8 /* GLDTweenBlock.h */,
192 | 3D5366F719DC337F0017C6B8 /* GLDTweenBlock.m */,
193 | );
194 | name = core;
195 | sourceTree = "";
196 | };
197 | /* End PBXGroup section */
198 |
199 | /* Begin PBXNativeTarget section */
200 | 3DAE9D1819DB9D30003692A1 /* GLDTween */ = {
201 | isa = PBXNativeTarget;
202 | buildConfigurationList = 3DAE9D3C19DB9D30003692A1 /* Build configuration list for PBXNativeTarget "GLDTween" */;
203 | buildPhases = (
204 | 3DAE9D1519DB9D30003692A1 /* Sources */,
205 | 3DAE9D1619DB9D30003692A1 /* Frameworks */,
206 | 3DAE9D1719DB9D30003692A1 /* Resources */,
207 | );
208 | buildRules = (
209 | );
210 | dependencies = (
211 | );
212 | name = GLDTween;
213 | productName = GLDTween;
214 | productReference = 3DAE9D1919DB9D30003692A1 /* GLDTween.app */;
215 | productType = "com.apple.product-type.application";
216 | };
217 | 3DAE9D3119DB9D30003692A1 /* GLDTweenTests */ = {
218 | isa = PBXNativeTarget;
219 | buildConfigurationList = 3DAE9D3F19DB9D30003692A1 /* Build configuration list for PBXNativeTarget "GLDTweenTests" */;
220 | buildPhases = (
221 | 3DAE9D2E19DB9D30003692A1 /* Sources */,
222 | 3DAE9D2F19DB9D30003692A1 /* Frameworks */,
223 | 3DAE9D3019DB9D30003692A1 /* Resources */,
224 | );
225 | buildRules = (
226 | );
227 | dependencies = (
228 | 3DAE9D3419DB9D30003692A1 /* PBXTargetDependency */,
229 | );
230 | name = GLDTweenTests;
231 | productName = GLDTweenTests;
232 | productReference = 3DAE9D3219DB9D30003692A1 /* GLDTweenTests.xctest */;
233 | productType = "com.apple.product-type.bundle.unit-test";
234 | };
235 | /* End PBXNativeTarget section */
236 |
237 | /* Begin PBXProject section */
238 | 3DAE9D1119DB9D30003692A1 /* Project object */ = {
239 | isa = PBXProject;
240 | attributes = {
241 | LastUpgradeCheck = 0600;
242 | ORGANIZATIONNAME = "THE GUILD";
243 | TargetAttributes = {
244 | 3DAE9D1819DB9D30003692A1 = {
245 | CreatedOnToolsVersion = 6.0.1;
246 | };
247 | 3DAE9D3119DB9D30003692A1 = {
248 | CreatedOnToolsVersion = 6.0.1;
249 | TestTargetID = 3DAE9D1819DB9D30003692A1;
250 | };
251 | };
252 | };
253 | buildConfigurationList = 3DAE9D1419DB9D30003692A1 /* Build configuration list for PBXProject "GLDTween" */;
254 | compatibilityVersion = "Xcode 3.2";
255 | developmentRegion = English;
256 | hasScannedForEncodings = 0;
257 | knownRegions = (
258 | en,
259 | Base,
260 | );
261 | mainGroup = 3DAE9D1019DB9D30003692A1;
262 | productRefGroup = 3DAE9D1A19DB9D30003692A1 /* Products */;
263 | projectDirPath = "";
264 | projectRoot = "";
265 | targets = (
266 | 3DAE9D1819DB9D30003692A1 /* GLDTween */,
267 | 3DAE9D3119DB9D30003692A1 /* GLDTweenTests */,
268 | );
269 | };
270 | /* End PBXProject section */
271 |
272 | /* Begin PBXResourcesBuildPhase section */
273 | 3DAE9D1719DB9D30003692A1 /* Resources */ = {
274 | isa = PBXResourcesBuildPhase;
275 | buildActionMask = 2147483647;
276 | files = (
277 | 3DAE9D2819DB9D30003692A1 /* Main.storyboard in Resources */,
278 | 3DAE9D2D19DB9D30003692A1 /* LaunchScreen.xib in Resources */,
279 | 3DAE9D2A19DB9D30003692A1 /* Images.xcassets in Resources */,
280 | );
281 | runOnlyForDeploymentPostprocessing = 0;
282 | };
283 | 3DAE9D3019DB9D30003692A1 /* Resources */ = {
284 | isa = PBXResourcesBuildPhase;
285 | buildActionMask = 2147483647;
286 | files = (
287 | );
288 | runOnlyForDeploymentPostprocessing = 0;
289 | };
290 | /* End PBXResourcesBuildPhase section */
291 |
292 | /* Begin PBXSourcesBuildPhase section */
293 | 3DAE9D1519DB9D30003692A1 /* Sources */ = {
294 | isa = PBXSourcesBuildPhase;
295 | buildActionMask = 2147483647;
296 | files = (
297 | 3D5366F519DC31D10017C6B8 /* GLDTweenSelector.m in Sources */,
298 | 3D53670C19DE16270017C6B8 /* TouchDemoViewController.m in Sources */,
299 | 3DAE9D2219DB9D30003692A1 /* AppDelegate.m in Sources */,
300 | 3D53675419DEE4550017C6B8 /* GLDEasingPlugin.m in Sources */,
301 | 3DAE9D1F19DB9D30003692A1 /* main.m in Sources */,
302 | 3DAE9D4D19DBB3C9003692A1 /* GLDTweenProperty.m in Sources */,
303 | 3DAE9D4519DB9DA0003692A1 /* GLDTween.m in Sources */,
304 | 3D53675519DEE4550017C6B8 /* GLDTweenPropertyPlugin.m in Sources */,
305 | 3D5366F819DC337F0017C6B8 /* GLDTweenBlock.m in Sources */,
306 | 3DAE9D5319DBB5EE003692A1 /* GLDTweenTween.m in Sources */,
307 | );
308 | runOnlyForDeploymentPostprocessing = 0;
309 | };
310 | 3DAE9D2E19DB9D30003692A1 /* Sources */ = {
311 | isa = PBXSourcesBuildPhase;
312 | buildActionMask = 2147483647;
313 | files = (
314 | 3DAE9D3919DB9D30003692A1 /* GLDTweenTests.m in Sources */,
315 | );
316 | runOnlyForDeploymentPostprocessing = 0;
317 | };
318 | /* End PBXSourcesBuildPhase section */
319 |
320 | /* Begin PBXTargetDependency section */
321 | 3DAE9D3419DB9D30003692A1 /* PBXTargetDependency */ = {
322 | isa = PBXTargetDependency;
323 | target = 3DAE9D1819DB9D30003692A1 /* GLDTween */;
324 | targetProxy = 3DAE9D3319DB9D30003692A1 /* PBXContainerItemProxy */;
325 | };
326 | /* End PBXTargetDependency section */
327 |
328 | /* Begin PBXVariantGroup section */
329 | 3DAE9D2619DB9D30003692A1 /* Main.storyboard */ = {
330 | isa = PBXVariantGroup;
331 | children = (
332 | 3DAE9D2719DB9D30003692A1 /* Base */,
333 | );
334 | name = Main.storyboard;
335 | sourceTree = "";
336 | };
337 | 3DAE9D2B19DB9D30003692A1 /* LaunchScreen.xib */ = {
338 | isa = PBXVariantGroup;
339 | children = (
340 | 3DAE9D2C19DB9D30003692A1 /* Base */,
341 | );
342 | name = LaunchScreen.xib;
343 | sourceTree = "";
344 | };
345 | /* End PBXVariantGroup section */
346 |
347 | /* Begin XCBuildConfiguration section */
348 | 3DAE9D3A19DB9D30003692A1 /* Debug */ = {
349 | isa = XCBuildConfiguration;
350 | buildSettings = {
351 | ALWAYS_SEARCH_USER_PATHS = NO;
352 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
353 | CLANG_CXX_LIBRARY = "libc++";
354 | CLANG_ENABLE_MODULES = YES;
355 | CLANG_ENABLE_OBJC_ARC = YES;
356 | CLANG_WARN_BOOL_CONVERSION = YES;
357 | CLANG_WARN_CONSTANT_CONVERSION = YES;
358 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
359 | CLANG_WARN_EMPTY_BODY = YES;
360 | CLANG_WARN_ENUM_CONVERSION = YES;
361 | CLANG_WARN_INT_CONVERSION = YES;
362 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
363 | CLANG_WARN_UNREACHABLE_CODE = YES;
364 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
365 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
366 | COPY_PHASE_STRIP = NO;
367 | ENABLE_STRICT_OBJC_MSGSEND = YES;
368 | GCC_C_LANGUAGE_STANDARD = gnu99;
369 | GCC_DYNAMIC_NO_PIC = NO;
370 | GCC_OPTIMIZATION_LEVEL = 0;
371 | GCC_PREPROCESSOR_DEFINITIONS = (
372 | "DEBUG=1",
373 | "$(inherited)",
374 | );
375 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
376 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
377 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
378 | GCC_WARN_UNDECLARED_SELECTOR = YES;
379 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
380 | GCC_WARN_UNUSED_FUNCTION = YES;
381 | GCC_WARN_UNUSED_VARIABLE = YES;
382 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
383 | MTL_ENABLE_DEBUG_INFO = YES;
384 | ONLY_ACTIVE_ARCH = YES;
385 | SDKROOT = iphoneos;
386 | };
387 | name = Debug;
388 | };
389 | 3DAE9D3B19DB9D30003692A1 /* Release */ = {
390 | isa = XCBuildConfiguration;
391 | buildSettings = {
392 | ALWAYS_SEARCH_USER_PATHS = NO;
393 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
394 | CLANG_CXX_LIBRARY = "libc++";
395 | CLANG_ENABLE_MODULES = YES;
396 | CLANG_ENABLE_OBJC_ARC = YES;
397 | CLANG_WARN_BOOL_CONVERSION = YES;
398 | CLANG_WARN_CONSTANT_CONVERSION = YES;
399 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
400 | CLANG_WARN_EMPTY_BODY = YES;
401 | CLANG_WARN_ENUM_CONVERSION = YES;
402 | CLANG_WARN_INT_CONVERSION = YES;
403 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
404 | CLANG_WARN_UNREACHABLE_CODE = YES;
405 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
406 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
407 | COPY_PHASE_STRIP = YES;
408 | ENABLE_NS_ASSERTIONS = NO;
409 | ENABLE_STRICT_OBJC_MSGSEND = YES;
410 | GCC_C_LANGUAGE_STANDARD = gnu99;
411 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
412 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
413 | GCC_WARN_UNDECLARED_SELECTOR = YES;
414 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
415 | GCC_WARN_UNUSED_FUNCTION = YES;
416 | GCC_WARN_UNUSED_VARIABLE = YES;
417 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
418 | MTL_ENABLE_DEBUG_INFO = NO;
419 | SDKROOT = iphoneos;
420 | VALIDATE_PRODUCT = YES;
421 | };
422 | name = Release;
423 | };
424 | 3DAE9D3D19DB9D30003692A1 /* Debug */ = {
425 | isa = XCBuildConfiguration;
426 | buildSettings = {
427 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
428 | CODE_SIGN_IDENTITY = "iPhone Developer";
429 | INFOPLIST_FILE = GLDTween/Info.plist;
430 | IPHONEOS_DEPLOYMENT_TARGET = 6.0;
431 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
432 | PRODUCT_NAME = "$(TARGET_NAME)";
433 | };
434 | name = Debug;
435 | };
436 | 3DAE9D3E19DB9D30003692A1 /* Release */ = {
437 | isa = XCBuildConfiguration;
438 | buildSettings = {
439 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
440 | CODE_SIGN_IDENTITY = "iPhone Developer";
441 | INFOPLIST_FILE = GLDTween/Info.plist;
442 | IPHONEOS_DEPLOYMENT_TARGET = 6.0;
443 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
444 | PRODUCT_NAME = "$(TARGET_NAME)";
445 | };
446 | name = Release;
447 | };
448 | 3DAE9D4019DB9D30003692A1 /* Debug */ = {
449 | isa = XCBuildConfiguration;
450 | buildSettings = {
451 | BUNDLE_LOADER = "$(TEST_HOST)";
452 | FRAMEWORK_SEARCH_PATHS = (
453 | "$(SDKROOT)/Developer/Library/Frameworks",
454 | "$(inherited)",
455 | );
456 | GCC_PREPROCESSOR_DEFINITIONS = (
457 | "DEBUG=1",
458 | "$(inherited)",
459 | );
460 | INFOPLIST_FILE = GLDTweenTests/Info.plist;
461 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
462 | PRODUCT_NAME = "$(TARGET_NAME)";
463 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/GLDTween.app/GLDTween";
464 | };
465 | name = Debug;
466 | };
467 | 3DAE9D4119DB9D30003692A1 /* Release */ = {
468 | isa = XCBuildConfiguration;
469 | buildSettings = {
470 | BUNDLE_LOADER = "$(TEST_HOST)";
471 | FRAMEWORK_SEARCH_PATHS = (
472 | "$(SDKROOT)/Developer/Library/Frameworks",
473 | "$(inherited)",
474 | );
475 | INFOPLIST_FILE = GLDTweenTests/Info.plist;
476 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
477 | PRODUCT_NAME = "$(TARGET_NAME)";
478 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/GLDTween.app/GLDTween";
479 | };
480 | name = Release;
481 | };
482 | /* End XCBuildConfiguration section */
483 |
484 | /* Begin XCConfigurationList section */
485 | 3DAE9D1419DB9D30003692A1 /* Build configuration list for PBXProject "GLDTween" */ = {
486 | isa = XCConfigurationList;
487 | buildConfigurations = (
488 | 3DAE9D3A19DB9D30003692A1 /* Debug */,
489 | 3DAE9D3B19DB9D30003692A1 /* Release */,
490 | );
491 | defaultConfigurationIsVisible = 0;
492 | defaultConfigurationName = Release;
493 | };
494 | 3DAE9D3C19DB9D30003692A1 /* Build configuration list for PBXNativeTarget "GLDTween" */ = {
495 | isa = XCConfigurationList;
496 | buildConfigurations = (
497 | 3DAE9D3D19DB9D30003692A1 /* Debug */,
498 | 3DAE9D3E19DB9D30003692A1 /* Release */,
499 | );
500 | defaultConfigurationIsVisible = 0;
501 | defaultConfigurationName = Release;
502 | };
503 | 3DAE9D3F19DB9D30003692A1 /* Build configuration list for PBXNativeTarget "GLDTweenTests" */ = {
504 | isa = XCConfigurationList;
505 | buildConfigurations = (
506 | 3DAE9D4019DB9D30003692A1 /* Debug */,
507 | 3DAE9D4119DB9D30003692A1 /* Release */,
508 | );
509 | defaultConfigurationIsVisible = 0;
510 | defaultConfigurationName = Release;
511 | };
512 | /* End XCConfigurationList section */
513 | };
514 | rootObject = 3DAE9D1119DB9D30003692A1 /* Project object */;
515 | }
516 |
--------------------------------------------------------------------------------
/GLDTween/GLDTween.m:
--------------------------------------------------------------------------------
1 | //
2 | // GLDTween.m
3 | // GLDTween
4 | //
5 | // Created by Takayuki Fukatsu on 2014/10/01.
6 | // Copyright (c) 2014 THE GUILD. All rights reserved.
7 | //
8 |
9 | #import "GLDTween.h"
10 | #import "GLDTweenProperty.h"
11 | #import "GLDTweenPropertyPlugin.h"
12 | #import "GLDEasingPlugin.h"
13 |
14 |
15 | NSString *const GLDEasingNone = @"EaseNone";
16 | NSString *const GLDEasingInQuad = @"EaseInQuad";
17 | NSString *const GLDEasingOutQuad = @"EaseOutQuad";
18 | NSString *const GLDEasingInOutQuad = @"EaseInOutQuad";
19 | NSString *const GLDEasingInCubic = @"EaseInCubic";
20 | NSString *const GLDEasingOutCubic = @"EaseOutCubic";
21 | NSString *const GLDEasingInOutCubic = @"EaseInOutCubic";
22 | NSString *const GLDEasingInQuart = @"EaseInQuart";
23 | NSString *const GLDEasingOutQuart = @"EaseOutQuart";
24 | NSString *const GLDEasingInOutQuart = @"EaseInOutQuart";
25 | NSString *const GLDEasingInQuint = @"EaseInQuint";
26 | NSString *const GLDEasingOutQuint = @"EaseOutQuint";
27 | NSString *const GLDEasingInOutQuint = @"EaseInOutQuint";
28 | NSString *const GLDEasingInSine = @"EaseInSine";
29 | NSString *const GLDEasingOutSine = @"EaseOutSine";
30 | NSString *const GLDEasingInOutSine = @"EaseInOutSine";
31 | NSString *const GLDEasingInCirc = @"EaseInCirc";
32 | NSString *const GLDEasingOutCirc = @"EaseOutCirc";
33 | NSString *const GLDEasingInOutCirc = @"EaseInOutCirc";
34 | NSString *const GLDEasingInExpo = @"EaseInExpo";
35 | NSString *const GLDEasingOutExpo = @"EaseOutExpo";
36 | NSString *const GLDEasingInOutExpo = @"EaseInOutExpo";
37 | NSString *const GLDEasingInBack = @"EaseInBack";
38 | NSString *const GLDEasingOutBack = @"EaseOutBack";
39 | NSString *const GLDEasingInOutBack = @"EaseInOutBack";
40 | NSString *const GLDEasingInBounce = @"EaseInBounce";
41 | NSString *const GLDEasingOutBounce = @"EaseOutBounce";
42 | NSString *const GLDEasingInOutBounce = @"EaseInOutBounce";
43 | NSString *const GLDEasingInElastic = @"EaseInElastic";
44 | NSString *const GLDEasingOutElastic = @"EaseOutElastic";
45 | NSString *const GLDEasingInOutElastic = @"EaseInOutElastic";
46 |
47 | NSString *const GLDTweenParamDuration = @"duration";
48 | NSString *const GLDTweenParamDelay = @"delay";
49 | NSString *const GLDTweenParamRepeat = @"repeat";
50 | NSString *const GLDTweenParamEasing = @"easing";
51 | NSString *const GLDTweenParamRounded = @"rounded";
52 | NSString *const GLDTweenParamStartSelector = @"startSelector";
53 | NSString *const GLDTweenParamUpdateSelector = @"updateSelector";
54 | NSString *const GLDTweenParamRepeatSelector = @"repeatSelector";
55 | NSString *const GLDTweenParamCompletionSelector = @"completionSelector";
56 | NSString *const GLDTweenParamStartBlock = @"startBlock";
57 | NSString *const GLDTweenParamUpdateBlock = @"updateBlock";
58 | NSString *const GLDTweenParamRepeatBlock = @"repeatBlock";
59 | NSString *const GLDTweenParamCompletionBlock = @"completionBLock";
60 | NSString *const GLDTweenParamRepeatsDelay = @"repeatsDelay";
61 | NSString *const GLDTweenParamLocksInteraction = @"locksInteraction";
62 | NSString *const GLDTweenParamUnlocksInteraction = @"unlocksInteraction";
63 |
64 |
65 | @implementation GLDTween {
66 | //Time Management
67 | CADisplayLink *displayLink;
68 | NSTimeInterval currentTime;
69 |
70 | //Data Containers
71 | NSMutableArray *tweens;
72 | NSMutableDictionary *easings;
73 | NSMutableDictionary *specialProperties;
74 |
75 | //Name Table
76 | NSMutableArray *easingNames;
77 | NSMutableDictionary *reservedPropertyNames;
78 | }
79 |
80 | #pragma mark - Public
81 |
82 |
83 | /**
84 | アニメーションの登録。
85 |
86 | @param target アニメーションの対象となるオブジェクト
87 | @param params アニメーションのパラメータとなるNSDictionary
88 | @return BOOL アニメーションの登録に成功したかのBOOL値
89 | */
90 | + (BOOL)addTween:(NSObject *)target withParams:(NSDictionary *)params {
91 | return [[GLDTween sharedEngine] addTween:target withParams:params];
92 | }
93 |
94 |
95 | + (BOOL)removeTween:(NSObject *)target {
96 | return [[GLDTween sharedEngine] removeTween:target];
97 | }
98 |
99 |
100 | + (BOOL)removeTweens:(NSArray *)targets {
101 | return [[GLDTween sharedEngine] removeTweens:targets];
102 | }
103 |
104 |
105 | + (BOOL)removeTween:(NSObject *)target withProps:(NSArray *)props {
106 | return [[GLDTween sharedEngine] removeTween:target withProps:props];
107 | }
108 |
109 |
110 | + (BOOL)removeAllTweens {
111 | return [[GLDTween sharedEngine] removeAllTweens];
112 | }
113 |
114 |
115 | + (BOOL)pauseTween:(NSObject *)target {
116 | return [[GLDTween sharedEngine] pauseTween:target];
117 | }
118 |
119 |
120 | + (BOOL)pauseTweens:(NSArray *)targets {
121 | return [[GLDTween sharedEngine] pauseTweens:targets];
122 | }
123 |
124 |
125 | + (BOOL)pauseAllTweens {
126 | return [[GLDTween sharedEngine] pauseAllTweens];
127 | }
128 |
129 |
130 | + (BOOL)resumeTween:(NSObject *)target {
131 | return [[GLDTween sharedEngine] resumeTween:target];
132 | }
133 |
134 |
135 | + (BOOL)resumeTweens:(NSArray *)targets {
136 | return [[GLDTween sharedEngine] resumeTweens:targets];
137 | }
138 |
139 |
140 | + (BOOL)resumeAllTweens {
141 | return [[GLDTween sharedEngine] resumeAllTweens];
142 | }
143 |
144 |
145 | + (NSArray *)easingNames {
146 | return [[GLDTween sharedEngine] easingNames];
147 | }
148 |
149 |
150 | + (BOOL)isTweening:(NSObject *)target {
151 | return [[GLDTween sharedEngine] isTweening:target];
152 | }
153 |
154 |
155 | /**
156 | Register custom Easing Curve as plugin.
157 |
158 | @param Class that extends GLDTweenEasingPlugin
159 | @param Name of Easing
160 | @return BOOL success
161 | */
162 | + (BOOL)registerEasingPlugin:(Class)class forKey:(NSString *)key {
163 | return [[GLDTween sharedEngine] registerEasingPlugin:class forKey:key];
164 | }
165 |
166 |
167 | /**
168 | Register custom Property behavior.
169 |
170 | @param Class that extends GLDTweenSpecialPropertyPlugin
171 | @param Name of property.
172 | @return BOOL success
173 | */
174 | + (BOOL)registerSpecialPropertyPlugin:(Class)class forKey:(NSString *)key {
175 | return [[GLDTween sharedEngine] registerSpecialPropertyPlugin:class forKey:key];
176 | }
177 |
178 |
179 | #pragma mark - Private Add
180 |
181 |
182 | - (BOOL)addTween:(NSObject *)target withParams:(NSDictionary *)params {
183 | float duration = [[params objectForKey:GLDTweenParamDuration] floatValue];
184 | float delay = [[params objectForKey:GLDTweenParamDelay] floatValue];
185 |
186 | //Create Tween Object
187 | GLDTweenTween *tween = [[GLDTweenTween alloc] init];
188 | tween.target = target;
189 | tween.startTime = currentTime + delay;
190 | tween.completeTime = currentTime + delay + duration;
191 | tween.repeat = [[params objectForKey:GLDTweenParamRepeat] intValue];
192 | tween.easing = [params objectForKey:GLDTweenParamEasing] ? (NSString *)[params objectForKey:GLDTweenParamEasing] : GLDEasingNone;
193 | if (!easings[tween.easing]) {
194 | [self logWarning:[NSString stringWithFormat:@"Specified easing not exists %@ %@.", target, tween.easing]];
195 | tween.easing = GLDEasingNone;
196 | }
197 | tween.rounded = ([params objectForKey:GLDTweenParamRounded] != nil);
198 | tween.repeatsDelay = ([params objectForKey:GLDTweenParamRepeatsDelay] != nil);
199 | tween.locksInteraction = ([params objectForKey:GLDTweenParamLocksInteraction] != nil);
200 | tween.unlocksInteraction = ([params objectForKey:GLDTweenParamUnlocksInteraction] != nil);
201 | tween.delay = delay;
202 |
203 | //Setup Event Handler
204 | tween.startSelector = [params objectForKey:GLDTweenParamStartSelector];
205 | tween.updateSelector = [params objectForKey:GLDTweenParamUpdateSelector];
206 | tween.repeatSelector = [params objectForKey:GLDTweenParamRepeatSelector];
207 | tween.completionSelector = [params objectForKey:GLDTweenParamCompletionSelector];
208 | tween.startBlock = [params objectForKey:GLDTweenParamStartBlock];
209 | tween.updateBlock = [params objectForKey:GLDTweenParamUpdateBlock];
210 | tween.repeatBlock = [params objectForKey:GLDTweenParamRepeatBlock];
211 | tween.completionBlock = [params objectForKey:GLDTweenParamCompletionBlock];
212 |
213 | //Insert Animatable Property
214 | for (NSString *key in params) {
215 | NSValue *value = [params objectForKey:key];
216 | GLDTweenProperty *property;
217 |
218 | //NSLog(@"-----------");
219 | //NSLog(@"Key %@", key);
220 | if ([self isReservedPropertyName:key]) {
221 | //This word is reserved. we don't treat it as animatable property.
222 | continue;
223 | } else {
224 | //This word is registerd as Special Property we use them instead
225 | if (specialProperties[key]) {
226 | NSString *specialPropertyClassName = specialProperties[key];
227 | Class specialPropertyClass = NSClassFromString(specialPropertyClassName);
228 | property = [[specialPropertyClass alloc] init];
229 | } else {
230 |
231 | @try {
232 | [tween.target valueForKey:key];
233 | }
234 | @catch (NSException *e) {
235 | [self logWarning:[NSString stringWithFormat:@"Tween property '%@' does not exists on %@. This will be ignored.", key, target.description]];
236 | continue;
237 | }
238 |
239 | if ([value isKindOfClass:[NSNumber class]]) {
240 | property = [[GLDTweenPropertyCGFloat alloc] init];
241 | } else if ([value isKindOfClass:[NSValue class]]) {
242 | if (strcmp(value.objCType, @encode(CGPoint)) == 0) {
243 | //CGPoint
244 | property = [[GLDTweenPropertyCGPoint alloc] init];
245 | } else if (strcmp(value.objCType, @encode(CGSize)) == 0) {
246 | //CGSize
247 | property = [[GLDTweenPropertyCGSize alloc] init];
248 | } else if (strcmp(value.objCType, @encode(CGRect)) == 0) {
249 | //CGRect
250 | property = [[GLDTweenPropertyCGRect alloc] init];
251 | } else if (strcmp(value.objCType, @encode(CGAffineTransform)) == 0) {
252 | //CGAffineTransform
253 | property = [[GLDTweenPropertyCGAffineTransform alloc] init];
254 | } else if (strcmp(value.objCType, @encode(CATransform3D)) == 0) {
255 | //CATranform3D
256 | property = [[GLDTweenPropertyCATransform3D alloc] init];
257 | } else {
258 | //Unknown DataType
259 | [self logWarning:[NSString stringWithFormat:@"Wrong Data Type %@ %@", key, value]];
260 | return FALSE;
261 | }
262 | } else {
263 | [self logWarning:[NSString stringWithFormat:@"Wrong Data Type %@ %@", key, value]];
264 | return FALSE;
265 | }
266 | }
267 | property.key = key;
268 | property.startValue = [property valueForTarget:target key:key];
269 | property.completeValue = value;
270 | property.rounded = tween.rounded;
271 | }
272 | if (property != nil) {
273 | [tween.properties setObject:property forKey:key];
274 | }
275 | }
276 |
277 | if (tween.locksInteraction) {
278 | [[UIApplication sharedApplication] beginIgnoringInteractionEvents];
279 | }
280 |
281 | //Add Tween
282 | [tweens addObject:tween];
283 |
284 | if (duration == 0.0 && delay == 0.0) {
285 | //quick execution for 0 duration.
286 | int index = tweens.count - 1.0;
287 | [self updateTweenByIndex:index];
288 | [self killTweenByIndex:index];
289 | }
290 | return TRUE;
291 | }
292 |
293 |
294 | #pragma mark - Private Pause
295 |
296 |
297 | - (BOOL)pauseTween:(NSObject *)target {
298 | BOOL result = NO;
299 | for (int i = 0; i < tweens.count; i++) {
300 | GLDTweenTween *tween = (GLDTweenTween *)tweens[i];
301 | if (target == tween.target && !tween.isPaused) {
302 | [self pauseTweenByIndex:i];
303 | result = YES;
304 | }
305 | }
306 | return result;
307 | }
308 |
309 |
310 | - (BOOL)pauseTweens:(NSArray *)targets {
311 | BOOL result = NO;
312 | for (int i = 0; i < targets.count; i++) {
313 | if ([self pauseTween:targets[i]]) {
314 | result = YES;
315 | }
316 | }
317 | return result;
318 | }
319 |
320 |
321 | - (BOOL)pauseAllTweens {
322 | BOOL result = NO;
323 | for (int i = 0; i < tweens.count; i++) {
324 | GLDTweenTween*tween = (GLDTweenTween *)tweens[i];
325 | if (!tween.isPaused) {
326 | [self pauseTweenByIndex:i];
327 | result = YES;
328 | }
329 | }
330 | return result;
331 | }
332 |
333 |
334 | - (BOOL)resumeTween:(NSObject *)target {
335 | BOOL result = NO;
336 | for (int i = 0; i < tweens.count; i++) {
337 | GLDTweenTween *tween = (GLDTweenTween *)tweens[i];
338 | if (target == tween.target && tween.isPaused) {
339 | [self resumeTweenByIndex:i];
340 | result = YES;
341 | }
342 | }
343 | return result;
344 | }
345 |
346 |
347 | - (BOOL)resumeTweens:(NSArray *)targets {
348 | BOOL result = NO;
349 | for (int i = 0; i < targets.count; i++) {
350 | if ([self resumeTween:targets[i]]) {
351 | result = YES;
352 | }
353 | }
354 | return result;
355 | }
356 |
357 |
358 | - (BOOL)resumeAllTweens {
359 | BOOL result = NO;
360 | for (int i = 0; i < tweens.count; i++) {
361 | GLDTweenTween*tween = (GLDTweenTween *)tweens[i];
362 | if (tween.isPaused) {
363 | [self resumeTweenByIndex:i];
364 | result = YES;
365 | }
366 | }
367 | return result;
368 | }
369 |
370 |
371 | #pragma mark - Private Remove
372 |
373 |
374 | - (BOOL)removeTween:(NSObject *)target {
375 | BOOL result = NO;
376 | for (int i = 0; i < tweens.count; i++) {
377 | GLDTweenTween *tween = (GLDTweenTween *)tweens[i];
378 | if (target == tween.target && !tween.killFlag) {
379 | [self killTweenByIndex:i];
380 | result = YES;
381 | }
382 | }
383 | return result;
384 | }
385 |
386 |
387 | - (BOOL)removeTweens:(NSArray *)targets {
388 | BOOL result = NO;
389 | for (int i = 0; i < targets.count; i++) {
390 | if ([self removeTween:targets[i]]) {
391 | result = YES;
392 | }
393 | }
394 | return result;
395 | }
396 |
397 | - (BOOL)removeTween:(NSObject *)target withProps:(NSArray *)props {
398 | BOOL result = FALSE;
399 | for (int i = 0; i < tweens.count; i++) {
400 | GLDTweenTween *tween = (GLDTweenTween *)tweens[i];
401 | if (target == tween.target && !tween.killFlag) {
402 | for (int j = 0; j < props.count; j++) {
403 | NSString *key = props[j];
404 | if (tween.properties[key]) {
405 | [tween.properties removeObjectForKey:key];
406 | result = TRUE;
407 | }
408 | }
409 | if (tween.properties.count == 0) {
410 | [self killTweenByIndex:i];
411 | result = TRUE;
412 | }
413 | }
414 | }
415 | return result;
416 | }
417 |
418 |
419 | //Method for overwrite
420 | - (BOOL)removeConflictedTweenWithTween:(GLDTweenTween *)tween {
421 | BOOL result = NO;
422 | for (int i = 0; i < tweens.count; i++) {
423 | GLDTweenTween *tw = tweens[i];
424 | if (tween == tw) {
425 | continue;
426 | }
427 | if (tween.target != tw.target) {
428 | continue;
429 | }
430 | if (tw.startTime < tween.startTime && tw.completeTime > tween.startTime) {
431 | //Need Overwrite
432 | NSArray *keys = [tw.properties allKeys];
433 | for (NSString*key in keys) {
434 | if (tween.properties[key]) {
435 | //Remove property from old tween
436 | [self logWarning:[NSString stringWithFormat:@"Duplicated property '%@' was over written.", key]];
437 | [tw.properties removeObjectForKey:key];
438 | result = YES;
439 | }
440 | }
441 | if (tw.properties.count == 0) {
442 | //NSLog(@"競合するTween%@を削除 %d", tw, i);
443 | [self killTweenByIndex:i];
444 | }
445 | }
446 | }
447 | return result;
448 | }
449 |
450 |
451 | - (BOOL)removeAllTweens {
452 | BOOL result = NO;
453 | for (int i = 0; i < tweens.count; i++) {
454 | if (!((GLDTweenTween *)tweens[i]).killFlag) {
455 | [self killTweenByIndex:i];
456 | result = YES;
457 | }
458 | }
459 | return result;
460 | }
461 |
462 |
463 | // TODO: optimize
464 | - (BOOL)isTweening:(NSObject *)target {
465 | for (int i = 0; i < tweens.count; i++) {
466 | GLDTweenTween *tw = (GLDTweenTween *)tweens[i];
467 | if (tw.target == target && !tw.killFlag) {
468 | return YES;
469 | }
470 | }
471 | return NO;
472 | }
473 |
474 |
475 | #pragma mark - Private Init
476 |
477 |
478 | + (GLDTween *)sharedEngine {
479 | static GLDTween *sharedEngine = nil;
480 | static dispatch_once_t onceToken;
481 | dispatch_once(&onceToken, ^{
482 | sharedEngine = [[GLDTween alloc] init];
483 | });
484 | return sharedEngine;
485 | }
486 |
487 |
488 | - (id)init {
489 | if (self = [super init]) {
490 | tweens = [[NSMutableArray alloc] initWithCapacity:100];
491 | easings = [[NSMutableDictionary alloc] initWithCapacity:10];
492 | easingNames = [[NSMutableArray alloc] initWithCapacity:10];
493 | specialProperties = [[NSMutableDictionary alloc] initWithCapacity:10];
494 | reservedPropertyNames = [[NSMutableDictionary alloc] initWithCapacity:10];
495 |
496 | //Register reserved property name
497 | [self registerReservedPropertyName:GLDTweenParamDuration];
498 | [self registerReservedPropertyName:GLDTweenParamDelay];
499 | [self registerReservedPropertyName:GLDTweenParamEasing];
500 | [self registerReservedPropertyName:GLDTweenParamRepeat];
501 | [self registerReservedPropertyName:GLDTweenParamRounded];
502 | [self registerReservedPropertyName:GLDTweenParamStartBlock];
503 | [self registerReservedPropertyName:GLDTweenParamUpdateBlock];
504 | [self registerReservedPropertyName:GLDTweenParamRepeatBlock];
505 | [self registerReservedPropertyName:GLDTweenParamCompletionBlock];
506 | [self registerReservedPropertyName:GLDTweenParamStartSelector];
507 | [self registerReservedPropertyName:GLDTweenParamUpdateSelector];
508 | [self registerReservedPropertyName:GLDTweenParamRepeatSelector];
509 | [self registerReservedPropertyName:GLDTweenParamCompletionSelector];
510 | [self registerReservedPropertyName:GLDTweenParamRepeatsDelay];
511 | [self registerReservedPropertyName:GLDTweenParamLocksInteraction];
512 | [self registerReservedPropertyName:GLDTweenParamUnlocksInteraction];
513 |
514 | //Register easing plugin
515 | [self registerEasingPlugin:[GLDEasingFunctionNone class] forKey:GLDEasingNone];
516 | [self registerEasingPlugin:[GLDEasingFunctionInQuad class] forKey:GLDEasingInQuad];
517 | [self registerEasingPlugin:[GLDEasingFunctionOutQuad class] forKey:GLDEasingOutQuad];
518 | [self registerEasingPlugin:[GLDEasingFunctionInOutQuad class] forKey:GLDEasingInOutQuad];
519 | [self registerEasingPlugin:[GLDEasingFunctionInCubic class] forKey:GLDEasingInCubic];
520 | [self registerEasingPlugin:[GLDEasingFunctionOutCubic class] forKey:GLDEasingOutCubic];
521 | [self registerEasingPlugin:[GLDEasingFunctionInOutCubic class] forKey:GLDEasingInOutCubic];
522 | [self registerEasingPlugin:[GLDEasingFunctionInQuart class] forKey:GLDEasingInQuart];
523 | [self registerEasingPlugin:[GLDEasingFunctionOutQuart class] forKey:GLDEasingOutQuart];
524 | [self registerEasingPlugin:[GLDEasingFunctionInOutQuart class] forKey:GLDEasingInOutQuart];
525 | [self registerEasingPlugin:[GLDEasingFunctionInQuint class] forKey:GLDEasingInQuint];
526 | [self registerEasingPlugin:[GLDEasingFunctionOutQuint class] forKey:GLDEasingOutQuint];
527 | [self registerEasingPlugin:[GLDEasingFunctionInOutQuint class] forKey:GLDEasingInOutQuint];
528 | [self registerEasingPlugin:[GLDEasingFunctionInSine class] forKey:GLDEasingInSine];
529 | [self registerEasingPlugin:[GLDEasingFunctionOutSine class] forKey:GLDEasingOutSine];
530 | [self registerEasingPlugin:[GLDEasingFunctionInOutSine class] forKey:GLDEasingInOutSine];
531 | [self registerEasingPlugin:[GLDEasingFunctionInCirc class] forKey:GLDEasingInCirc];
532 | [self registerEasingPlugin:[GLDEasingFunctionOutCirc class] forKey:GLDEasingOutCirc];
533 | [self registerEasingPlugin:[GLDEasingFunctionInOutCirc class] forKey:GLDEasingInOutCirc];
534 | [self registerEasingPlugin:[GLDEasingFunctionInExpo class] forKey:GLDEasingInExpo];
535 | [self registerEasingPlugin:[GLDEasingFunctionOutExpo class] forKey:GLDEasingOutExpo];
536 | [self registerEasingPlugin:[GLDEasingFunctionInOutExpo class] forKey:GLDEasingInOutExpo];
537 | [self registerEasingPlugin:[GLDEasingFunctionInBack class] forKey:GLDEasingInBack];
538 | [self registerEasingPlugin:[GLDEasingFunctionOutBack class] forKey:GLDEasingOutBack];
539 | [self registerEasingPlugin:[GLDEasingFunctionInOutBack class] forKey:GLDEasingInOutBack];
540 | [self registerEasingPlugin:[GLDEasingFunctionInBounce class] forKey:GLDEasingInBounce];
541 | [self registerEasingPlugin:[GLDEasingFunctionOutBounce class] forKey:GLDEasingOutBounce];
542 | [self registerEasingPlugin:[GLDEasingFunctionInOutBounce class] forKey:GLDEasingInOutBounce];
543 | [self registerEasingPlugin:[GLDEasingFunctionInElastic class] forKey:GLDEasingInElastic];
544 | [self registerEasingPlugin:[GLDEasingFunctionOutElastic class] forKey:GLDEasingOutElastic];
545 | [self registerEasingPlugin:[GLDEasingFunctionInOutElastic class] forKey:GLDEasingInOutElastic];
546 |
547 | //Register special property
548 | [self registerSpecialPropertyPlugin:[GLDTweenPropertyX class] forKey:@"x"];
549 | [self registerSpecialPropertyPlugin:[GLDTweenPropertyY class] forKey:@"y"];
550 | [self registerSpecialPropertyPlugin:[GLDTweenPropertyWidth class] forKey:@"width"];
551 | [self registerSpecialPropertyPlugin:[GLDTweenPropertyHeight class] forKey:@"height"];
552 | [self registerSpecialPropertyPlugin:[GLDTweenPropertyCenterX class] forKey:@"centerX"];
553 | [self registerSpecialPropertyPlugin:[GLDTweenPropertyCenterY class] forKey:@"centerY"];
554 | [self registerSpecialPropertyPlugin:[GLDTweenPropertyTransform3D class] forKey:@"transform3d"];
555 |
556 | [self start];
557 | }
558 | return self;
559 | }
560 |
561 |
562 | #pragma mark - Private Plugins
563 |
564 |
565 | - (BOOL)registerEasingPlugin:(Class)class forKey:(NSString *)key {
566 | // TODO: Show warning and override when same keyname is given.
567 | GLDEasingFunction *easing = [[class alloc] init];
568 | [easings setObject:easing forKey:key];
569 | [easingNames addObject:key];
570 | return YES;
571 | }
572 |
573 |
574 | - (BOOL)registerSpecialPropertyPlugin:(Class)class forKey:(NSString *)key {
575 | // TODO: Show warning and override when same keyname is given.
576 | NSString *className = NSStringFromClass(class);
577 | [specialProperties setObject:className forKey:key];
578 | return YES;
579 | }
580 |
581 |
582 | - (BOOL)registerReservedPropertyName:(NSString *)name {
583 | [reservedPropertyNames setObject:@YES forKey:name];
584 | return YES;
585 | }
586 |
587 |
588 | #pragma mark - Private Internal Manipulation
589 |
590 |
591 | - (BOOL)pauseTweenByIndex:(int)index {
592 | GLDTweenTween *tween = (GLDTweenTween *)tweens[index];
593 | if (tween.isPaused) {
594 | return NO;
595 | }
596 | tween.pausedTime = currentTime;
597 | tween.paused = YES;
598 | return YES;
599 | }
600 |
601 |
602 | - (BOOL)resumeTweenByIndex:(int)index {
603 | GLDTweenTween *tween = (GLDTweenTween *)tweens[index];
604 | if (!tween.isPaused) {
605 | return FALSE;
606 | }
607 | tween.startTime = tween.startTime + currentTime - tween.completeTime;
608 | tween.completeTime = tween.completeTime + currentTime - tween.pausedTime;
609 | tween.pausedTime = 0;
610 | tween.paused = FALSE;
611 | return TRUE;
612 | }
613 |
614 |
615 | - (BOOL)killTweenByIndex:(int)index {
616 | GLDTweenTween *tween = tweens[index];
617 | if (tween.unlocksInteraction) {
618 | [[UIApplication sharedApplication] endIgnoringInteractionEvents];
619 | }
620 | tween.killFlag = YES;
621 | return YES;
622 | }
623 |
624 |
625 | - (BOOL)teardownTween:(GLDTweenTween *)tween {
626 | [tweens removeObject:tween];
627 | return YES;
628 | }
629 |
630 |
631 | #pragma mark - Private Update
632 |
633 |
634 | - (void)start {
635 | if (displayLink) {
636 | [displayLink invalidate];
637 | }
638 | displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(update:)];
639 | [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
640 | [self update:nil];
641 | }
642 |
643 |
644 | - (void)update:(id)sender {
645 | [self updateTimestamp];
646 | [self updateTweens];
647 | [self teardownTweens];
648 | }
649 |
650 |
651 | - (void)updateTimestamp {
652 | currentTime = [[NSDate date] timeIntervalSince1970];
653 | }
654 |
655 |
656 | - (void)updateTweens {
657 | for (int i = 0; i < tweens.count; i++) {
658 | GLDTweenTween *tween = tweens[i];
659 | if (!tween.isPaused && !tween.killFlag) {
660 | [self updateTweenByIndex:i];
661 | }
662 | }
663 | }
664 |
665 |
666 | /**
667 | Cleanup killed tween from data
668 | */
669 | - (BOOL)teardownTweens {
670 | BOOL result = NO;
671 | for (long i = tweens.count - 1; i > -1; i--) {
672 | GLDTweenTween *tween = tweens[i];
673 | if (tween.killFlag) {
674 | [self teardownTween:tween];
675 | }
676 | result = YES;
677 | }
678 | return result;
679 | }
680 |
681 |
682 | - (BOOL)updateTweenByIndex:(int)index {
683 | GLDTweenTween *tween = tweens[index];
684 | BOOL willComplete = NO;
685 |
686 | if (currentTime >= tween.completeTime) {
687 | willComplete = YES;
688 | }
689 |
690 | //Update
691 | if (tween.startTime <= currentTime) {
692 | if (!tween.hasStarted) {
693 | for (NSString *key in tween.properties) {
694 | GLDTweenProperty *property = [tween.properties objectForKey:key];
695 | [property updateStartValueForTarget:tween.target key:key];
696 | }
697 | tween.started = YES;
698 |
699 | [self removeConflictedTweenWithTween:tween];
700 |
701 | //Invoke Start Block and Selector
702 | if (tween.startBlock) {
703 | [tween.startBlock execute];
704 | }
705 | if (tween.startSelector) {
706 | [tween.startSelector perform];
707 | }
708 | }
709 |
710 | //Inject Tween
711 | float t = currentTime - tween.startTime;
712 | float d = tween.completeTime - tween.startTime;
713 | GLDEasingFunction *ease = easings[tween.easing];
714 | for (NSString *key in tween.properties) {
715 | GLDTweenProperty *property = [tween.properties objectForKey:key];
716 | if (willComplete) {
717 | [property setCompleteValueForTarget:tween.target key:key];
718 | } else {
719 | [property setTweenValueForTarget:tween.target key:key time:t duration:d ease:ease];
720 | }
721 | }
722 |
723 | //Update Callback
724 | if (tween.updateBlock) {
725 | [tween.updateBlock execute];
726 | }
727 | if (tween.updateSelector) {
728 | [tween.updateSelector perform];
729 | }
730 | }
731 |
732 | if (willComplete) {
733 | //Repeat
734 |
735 | if (tween.repeat != 0) {
736 | if (tween.repeat > 0) {
737 | tween.repeat--;
738 | }
739 | tween.completed = NO;
740 | tween.completeTime = (tween.completeTime - tween.startTime) + currentTime;
741 | tween.startTime = currentTime;
742 | if (tween.repeatsDelay) {
743 | tween.completeTime += tween.delay;
744 | tween.startTime += tween.delay;
745 | }
746 | if (tween.repeatBlock) {
747 | [tween.repeatBlock execute];
748 | }
749 | if (tween.repeatSelector) {
750 | [tween.completionSelector perform];
751 | }
752 | return TRUE;
753 | }
754 | tween.completed = YES;
755 |
756 | //Invoke Completion Completion Selector and Block
757 | if (tween.completionBlock) {
758 | [tween.completionBlock execute];
759 | }
760 | if (tween.completionSelector) {
761 | [tween.completionSelector perform];
762 | }
763 |
764 | [self killTweenByIndex:index];
765 | }
766 |
767 | return FALSE;
768 | }
769 |
770 |
771 | #pragma mark - Private Helper
772 |
773 |
774 | - (NSArray *)easingNames {
775 | return easingNames;
776 | }
777 |
778 |
779 | - (BOOL)isReservedPropertyName:(NSString *)name {
780 | return reservedPropertyNames[name] ? YES : NO;
781 | }
782 |
783 |
784 | - (void)logWarning:(NSString *)string {
785 | NSString *warning = [NSString stringWithFormat:@"WARNING: %@", string];
786 | NSLog(@"%@", warning);
787 | }
788 |
789 |
790 | @end
791 |
792 |
--------------------------------------------------------------------------------