Skip to content

Commit 9cbef5c

Browse files
committed
[ADDED] Cube animation
1 parent 99be6bb commit 9cbef5c

13 files changed

+554
-1
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//
2+
// CubeNavigationAnimator.h
3+
// MovieQuiz
4+
//
5+
// Created by Andrés Brun on 27/10/13.
6+
// Copyright (c) 2013 Andrés Brun. All rights reserved.
7+
//
8+
9+
#import <Foundation/Foundation.h>
10+
#import "CEReversibleAnimationController.h"
11+
12+
typedef enum {CubeAnimationWayHorizontal, CubeAnimationWayVertical} CubeAnimationWay;
13+
typedef enum {CubeAnimationTypeNormal, CubeAnimationTypeInverse} CubeAnimationType;
14+
15+
@interface CECubeAnimationController : CEReversibleAnimationController
16+
17+
@property (nonatomic, assign) CubeAnimationWay cubeAnimationWay;
18+
@property (nonatomic, assign) CubeAnimationType cubeAnimationType;
19+
20+
@end
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
//
2+
// CubeNavigationAnimator.m
3+
// MovieQuiz
4+
//
5+
// Created by Andrés Brun on 27/10/13.
6+
// Copyright (c) 2013 Andrés Brun. All rights reserved.
7+
//
8+
9+
#import "CECubeAnimationController.h"
10+
11+
#import "UIView+ABExtras.h"
12+
#import "UIImageView+ABExtras.h"
13+
#import "UINavigationController+ABExtras.h"
14+
15+
#define PERSPECTIVE -1.0 / 200.0
16+
#define ROTATION_ANGLE M_PI_2
17+
18+
#define TIME_ANIMATION 0.7
19+
20+
@implementation CECubeAnimationController
21+
22+
- (id)init
23+
{
24+
self = [super init];
25+
if (self) {
26+
self.cubeAnimationWay = CubeAnimationWayHorizontal;
27+
self.cubeAnimationType = CubeAnimationTypeNormal;
28+
29+
}
30+
31+
return self;
32+
}
33+
34+
-(NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext
35+
{
36+
return TIME_ANIMATION;
37+
}
38+
39+
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext fromVC:(UIViewController *)fromVC toVC:(UIViewController *)toVC fromView:(UIView *)fromView toView:(UIView *)toView
40+
{
41+
42+
int dir=0;
43+
switch (self.cubeAnimationType) {
44+
case CubeAnimationTypeNormal:
45+
dir=self.reverse?-1:1;
46+
break;
47+
case CubeAnimationTypeInverse:
48+
dir=self.reverse?1:-1;
49+
break;
50+
51+
default:
52+
break;
53+
}
54+
55+
//Crete the differents 3D animations
56+
CATransform3D viewFromTransform;
57+
CATransform3D viewToTransform;
58+
59+
//We create a content view for do the translate animation
60+
UIView *generalContentView = [[UIView alloc] initWithFrame:transitionContext.containerView.bounds];
61+
switch (self.cubeAnimationWay) {
62+
case CubeAnimationWayHorizontal:
63+
viewFromTransform = CATransform3DMakeRotation(dir*ROTATION_ANGLE, 0.0, 1.0, 0.0);
64+
viewToTransform = CATransform3DMakeRotation(-dir*ROTATION_ANGLE, 0.0, 1.0, 0.0);
65+
[toView.layer setAnchorPoint:CGPointMake(dir==1?0:1, 0.5)];
66+
[fromView.layer setAnchorPoint:CGPointMake(dir==1?1:0, 0.5)];
67+
68+
[generalContentView setTransform:CGAffineTransformMakeTranslation(dir*(generalContentView.frame.size.width)/2.0, 0)];
69+
break;
70+
71+
case CubeAnimationWayVertical:
72+
viewFromTransform = CATransform3DMakeRotation(-dir*ROTATION_ANGLE, 1.0, 0.0, 0.0);
73+
viewToTransform = CATransform3DMakeRotation(dir*ROTATION_ANGLE, 1.0, 0.0, 0.0);
74+
[toView.layer setAnchorPoint:CGPointMake(0.5, dir==1?0:1)];
75+
[fromView.layer setAnchorPoint:CGPointMake(0.5, dir==1?1:0)];
76+
77+
[generalContentView setTransform:CGAffineTransformMakeTranslation(0, dir*(generalContentView.frame.size.height)/2.0)];
78+
break;
79+
80+
default:
81+
break;
82+
}
83+
84+
viewFromTransform.m34 = PERSPECTIVE;
85+
viewToTransform.m34 = PERSPECTIVE;
86+
87+
toView.layer.transform = viewToTransform;
88+
89+
//Create the shadow
90+
UIView *fromShadow = [fromView addOpacityWithColor:[UIColor blackColor]];
91+
UIView *toShadow = [toView addOpacityWithColor:[UIColor blackColor]];
92+
93+
[fromShadow setAlpha:0.0];
94+
[toShadow setAlpha:1.0];
95+
96+
[generalContentView addSubview:toView];
97+
[generalContentView addSubview:fromView];
98+
99+
// Add the toView to the container
100+
[[transitionContext containerView] addSubview:generalContentView];
101+
102+
[UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
103+
switch (self.cubeAnimationWay) {
104+
case CubeAnimationWayHorizontal:
105+
[generalContentView setTransform:CGAffineTransformMakeTranslation(-dir*generalContentView.frame.size.width/2.0, 0)];
106+
break;
107+
108+
case CubeAnimationWayVertical:
109+
[generalContentView setTransform:CGAffineTransformMakeTranslation(0, -dir*(generalContentView.frame.size.height)/2.0)];
110+
break;
111+
112+
default:
113+
break;
114+
}
115+
116+
fromView.layer.transform = viewFromTransform;
117+
toView.layer.transform = CATransform3DIdentity;
118+
119+
[fromShadow setAlpha:1.0];
120+
[toShadow setAlpha:0.0];
121+
122+
123+
}completion:^(BOOL finished) {
124+
125+
fromView.layer.transform = CATransform3DIdentity;
126+
toView.layer.transform = CATransform3DIdentity;
127+
[fromView.layer setAnchorPoint:CGPointMake(0.5f, 0.5f)];
128+
[toView.layer setAnchorPoint:CGPointMake(0.5f, 0.5f)];
129+
130+
[fromShadow removeFromSuperview];
131+
[toShadow removeFromSuperview];
132+
133+
[generalContentView removeFromSuperview];
134+
135+
//Relocated the views
136+
[[transitionContext containerView] addSubview:fromView];
137+
[[transitionContext containerView] addSubview:toView];
138+
[generalContentView removeFromSuperview];
139+
140+
if ([transitionContext transitionWasCancelled]) {
141+
[toView removeFromSuperview];
142+
} else {
143+
[fromView removeFromSuperview];
144+
}
145+
146+
// inform the context of completion
147+
[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
148+
149+
}];
150+
}
151+
152+
@end

AnimationControllers/CEReversibleAnimationController.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,6 @@
2323
*/
2424
@property (nonatomic, assign) NSTimeInterval duration;
2525

26+
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext fromVC:(UIViewController *)fromVC toVC:(UIViewController *)toVC fromView:(UIView *)fromView toView:(UIView *)toView;
27+
2628
@end
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//
2+
// NSObject+ABExtras.h
3+
// uSpeak
4+
//
5+
// Created by uSpeak on 28/05/13.
6+
// Copyright (c) 2013 uSpeak Ltd. All rights reserved.
7+
//
8+
9+
#import <Foundation/Foundation.h>
10+
11+
typedef void (^NSObjectPerformBlock)(id userObject);
12+
13+
@interface NSObject (ABExtras)
14+
- (void)performBlock:(void (^)(void))block afterDelay:(NSTimeInterval)delay;
15+
- (void)performAfterDelay:(float)delay thisBlock:(void (^)(BOOL finished))completion;
16+
- (void)performBlockInBackground:(NSObjectPerformBlock)performBlock completion:(NSObjectPerformBlock)completionBlock userObject:(id)userObject;
17+
18+
@end
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
//
2+
// NSObject+ABExtras.m
3+
// uSpeak
4+
//
5+
// Created by uSpeak on 28/05/13.
6+
// Copyright (c) 2013 uSpeak Ltd. All rights reserved.
7+
//
8+
9+
#import "NSObject+ABExtras.h"
10+
11+
@implementation NSObject (ABExtras)
12+
13+
- (void)performBlock:(void (^)(void))block
14+
afterDelay:(NSTimeInterval)delay
15+
{
16+
block = [block copy];
17+
[self performSelector:@selector(fireBlockAfterDelay:)
18+
withObject:block
19+
afterDelay:delay];
20+
}
21+
22+
- (void)fireBlockAfterDelay:(void (^)(void))block {
23+
block();
24+
}
25+
26+
- (void)performAfterDelay:(float)delay thisBlock:(void (^)(BOOL finished))completion{
27+
28+
[UIView animateWithDuration:delay
29+
animations: ^{
30+
31+
}completion:^(BOOL finished) {
32+
33+
if (completion) {
34+
completion(finished);
35+
}
36+
}];
37+
}
38+
39+
40+
- (void)performBlockInBackground:(NSObjectPerformBlock)performBlock completion:(NSObjectPerformBlock)completionBlock userObject:(id)userObject
41+
{
42+
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
43+
performBlock(userObject);
44+
dispatch_async(dispatch_get_main_queue(), ^{
45+
if (completionBlock) {
46+
completionBlock(userObject);
47+
}
48+
});
49+
});
50+
}
51+
@end
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//
2+
// UIImageView+ABExtras.h
3+
// SquaresFlipNavigationExample
4+
//
5+
// Created by Andrés Brun on 8/8/13.
6+
// Copyright (c) 2013 Andrés Brun. All rights reserved.
7+
//
8+
9+
#import <UIKit/UIKit.h>
10+
11+
#define TAG_IMAGE_VIEW 999
12+
13+
@interface UIImageView (ABExtras)
14+
15+
/**
16+
Methot that create a crop image from that imageView
17+
*/
18+
- (UIImageView *) createCrop: (CGRect) crop;
19+
/**
20+
Method that crates a view that contains that ImageView
21+
*/
22+
- (UIView *)createView;
23+
24+
@end
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
//
2+
// UIImageView+ABExtras.m
3+
// SquaresFlipNavigationExample
4+
//
5+
// Created by Andrés Brun on 8/8/13.
6+
// Copyright (c) 2013 Andrés Brun. All rights reserved.
7+
//
8+
9+
#import "UIImageView+ABExtras.h"
10+
#import <QuartzCore/QuartzCore.h>
11+
#import "UINavigationController+ABExtras.h"
12+
13+
@implementation UIImageView (ABExtras)
14+
15+
- (UIImageView *) createCrop: (CGRect) crop
16+
{
17+
CGImageRef imageRef = CGImageCreateWithImageInRect(self.image.CGImage, crop);
18+
UIImageView *imageViewCropped = [[UIImageView alloc] initWithImage:[UIImage imageWithCGImage:imageRef]];
19+
[imageViewCropped setFrame:crop];
20+
21+
[imageViewCropped setFrame:CGRectMake(imageViewCropped.frame.origin.x,
22+
imageViewCropped.frame.origin.y+self.frame.origin.y,
23+
imageViewCropped.frame.size.width,
24+
imageViewCropped.frame.size.height)];
25+
CGImageRelease(imageRef);
26+
return imageViewCropped;
27+
}
28+
29+
- (UIView *)createView
30+
{
31+
UIView *newView = [[UIView alloc] initWithFrame:self.frame];
32+
[self setTag:TAG_IMAGE_VIEW];
33+
[self setFrame:self.bounds];
34+
[newView addSubview:self];
35+
36+
return newView;
37+
}
38+
39+
@end
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//
2+
// UINavigationController+ABExtras.h
3+
// SquaresFlipNavigationExample
4+
//
5+
// Created by Andrés Brun on 8/8/13.
6+
// Copyright (c) 2013 Andrés Brun. All rights reserved.
7+
//
8+
9+
#import <UIKit/UIKit.h>
10+
11+
#define CURRENT_VERSION [[[UIDevice currentDevice] systemVersion] floatValue]
12+
#define IS_EARLIER_IOS7 ( CURRENT_VERSION < 7.0)
13+
14+
@interface UINavigationController (ABExtras)
15+
16+
/**
17+
Method that calculate the origin.y of the contain view
18+
*/
19+
- (float) calculateYPosition;
20+
21+
@end
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
//
2+
// UINavigationController+ABExtras.m
3+
// SquaresFlipNavigationExample
4+
//
5+
// Created by Andrés Brun on 8/8/13.
6+
// Copyright (c) 2013 Andrés Brun. All rights reserved.
7+
//
8+
9+
#import "UINavigationController+ABExtras.h"
10+
11+
@implementation UINavigationController (ABExtras)
12+
13+
14+
- (float) calculateYPosition
15+
{
16+
float yPosition=0;
17+
18+
UIInterfaceOrientation interfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation];
19+
20+
if (!self.navigationBarHidden) {
21+
if (UIInterfaceOrientationIsPortrait(interfaceOrientation)){
22+
yPosition += self.navigationBar.frame.size.height;
23+
}else{
24+
yPosition += self.navigationBar.frame.size.width;
25+
}
26+
}
27+
28+
if (IS_EARLIER_IOS7 && ![UIApplication sharedApplication].statusBarHidden){
29+
if (UIInterfaceOrientationIsPortrait(interfaceOrientation)){
30+
yPosition += [UIApplication sharedApplication].statusBarFrame.size.height;
31+
}else{
32+
yPosition += [UIApplication sharedApplication].statusBarFrame.size.width;
33+
}
34+
}
35+
36+
return yPosition;
37+
38+
}
39+
40+
@end

0 commit comments

Comments
 (0)