-
Notifications
You must be signed in to change notification settings - Fork 21
/
Copy pathUINavigationController+TRVSNavigationControllerTransition.m
132 lines (100 loc) · 4.36 KB
/
UINavigationController+TRVSNavigationControllerTransition.m
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
//
// UINavigationController+TRVSNavigationControllerTranslation.m
// Daft Co.
//
// Created by Travis Jeffery on 2012-10-21.
//
//
#import <QuartzCore/QuartzCore.h>
#import "UINavigationController+TRVSNavigationControllerTransition.h"
static CALayer *TRVSStillLayer = nil;
static CALayer *TRVSTransitioningLayer = nil;
static NSTimeInterval const TRVSTransitionDuration = .3f;
@interface TRVSNavigationControllerTransitionAnimiationDelegate : NSObject
- (void)animationDidStop:(CAAnimation *)animation finished:(BOOL)flag;
+ (TRVSNavigationControllerTransitionAnimiationDelegate *)sharedDelegate;
@end
@implementation TRVSNavigationControllerTransitionAnimiationDelegate
- (void)animationDidStop:(CAAnimation *)animation finished:(BOOL)flag {
[TRVSStillLayer removeFromSuperlayer];
[TRVSTransitioningLayer removeFromSuperlayer];
}
+ (TRVSNavigationControllerTransitionAnimiationDelegate *)sharedDelegate {
static dispatch_once_t onceToken;
__strong static id sharedDelegate = nil;
dispatch_once(&onceToken, ^{ sharedDelegate = [[self alloc] init]; });
return sharedDelegate;
}
@end
@implementation UINavigationController (TRVSNavigationControllerTransition)
- (void)trvs_pushViewControllerWithNavigationControllerTransition:
(UIViewController *)viewController {
TRVSStillLayer = [self trvs_layerSnapshotWithTransform:CATransform3DIdentity];
[self pushViewController:viewController animated:NO];
TRVSTransitioningLayer =
[self trvs_layerSnapshotWithTransform:CATransform3DIdentity];
TRVSTransitioningLayer.frame = (CGRect) {
{CGRectGetWidth(self.view.bounds), CGRectGetMinY(self.view.bounds)},
self.view.bounds.size};
[self.view.layer addSublayer:TRVSStillLayer];
[self.view.layer addSublayer:TRVSTransitioningLayer];
[CATransaction flush];
[TRVSStillLayer addAnimation:
[self trvs_animationWithTranslation:-CGRectGetWidth(self.view.bounds)]
forKey:nil];
[TRVSTransitioningLayer addAnimation:
[self trvs_animationWithTranslation:-CGRectGetWidth(self.view.bounds)]
forKey:nil];
}
- (void)trvs_popViewControllerWithNavigationControllerTransition {
TRVSStillLayer = [self trvs_layerSnapshotWithTransform:CATransform3DIdentity];
[self popViewControllerAnimated:NO];
TRVSTransitioningLayer =
[self trvs_layerSnapshotWithTransform:CATransform3DIdentity];
TRVSTransitioningLayer.frame = (CGRect) {
{-CGRectGetWidth(self.view.bounds), CGRectGetMinY(self.view.bounds)},
self.view.bounds.size};
[self.view.layer addSublayer:TRVSStillLayer];
[self.view.layer addSublayer:TRVSTransitioningLayer];
[CATransaction flush];
[TRVSStillLayer addAnimation:
[self trvs_animationWithTranslation:CGRectGetWidth(self.view.bounds)]
forKey:nil];
[TRVSTransitioningLayer addAnimation:
[self trvs_animationWithTranslation:CGRectGetWidth(self.view.bounds)]
forKey:nil];
}
#pragma mark - Private
- (CABasicAnimation *)trvs_animationWithTranslation:(CGFloat)translation {
CABasicAnimation *animation =
[CABasicAnimation animationWithKeyPath:@"transform"];
animation.toValue = [NSValue
valueWithCATransform3D:CATransform3DTranslate(
CATransform3DIdentity, translation, 0.f, 0.f)];
animation.duration = TRVSTransitionDuration;
animation.delegate =
[TRVSNavigationControllerTransitionAnimiationDelegate sharedDelegate];
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;
animation.timingFunction =
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
return animation;
}
- (CALayer *)trvs_layerSnapshotWithTransform:(CATransform3D)transform {
if (UIGraphicsBeginImageContextWithOptions) {
UIGraphicsBeginImageContextWithOptions(
self.view.bounds.size, NO, [UIScreen mainScreen].scale);
} else {
UIGraphicsBeginImageContext(self.view.bounds.size);
}
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *snapshot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
CALayer *snapshotLayer = [CALayer layer];
snapshotLayer.transform = transform;
snapshotLayer.anchorPoint = CGPointMake(1.f, 1.f);
snapshotLayer.frame = self.view.bounds;
snapshotLayer.contents = (id)snapshot.CGImage;
return snapshotLayer;
}
@end