Commit 3e4f79e9 authored by 汪洋's avatar 汪洋

GMPresentAnimation 初步成型,但是还需要拆分

parent 30d831fb
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
@interface GMPresentAnimation : NSObject<UIViewControllerAnimatedTransitioning> // 通过使用GMPresentAnimation,来自定义 push 动画
@property(nonatomic,assign)UINavigationControllerOperation transitionType; @interface GMPresentAnimation : NSObject <UIViewControllerAnimatedTransitioning>
@property(nonatomic, assign) UINavigationControllerOperation transitionType;
@end @end
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
#import "GMPresentAnimation.h" #import "GMPresentAnimation.h"
#import "UIViewController+PushType.h" #import "UIViewController+PushType.h"
@interface GMPresentAnimation() <UIViewControllerAnimatedTransitioning> @interface GMPresentAnimation ()
@property(nonatomic, assign) NSTimeInterval duration; @property(nonatomic, assign) NSTimeInterval duration;
@end @end
@implementation GMPresentAnimation @implementation GMPresentAnimation
...@@ -16,91 +16,74 @@ ...@@ -16,91 +16,74 @@
- (instancetype)init { - (instancetype)init {
// 默认 push 动画时间0.6 // 默认 push 动画时间0.6
if (self = [super init]) { if (self = [super init]) {
self.duration = 0.6; self.duration = 0.3;
} }
return self; return self;
} }
- (void)push:(id<UIViewControllerContextTransitioning>)transitionContext - (void)push:(id<UIViewControllerContextTransitioning>)transitionContext {
{ CGRect bounds = [[UIScreen mainScreen] bounds];
UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey]; UIView *fromView = [transitionContext viewForKey:UITransitionContextFromViewKey];
UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey]; UIView *toView = [transitionContext viewForKey:UITransitionContextToViewKey];
NSTimeInterval duration = [self transitionDuration:transitionContext];
CGRect bound = [[UIScreen mainScreen] bounds];
fromVC.view.hidden = YES;
// 在containerView上加一个toVC.snapshot,把之前页面当作背景
// 不加的话,toView在动画结束时会被系统移除,进而底部背景会突然变白
UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
fromVC.snapshot.frame = bounds;
[[transitionContext containerView] addSubview:fromVC.snapshot]; [[transitionContext containerView] addSubview:fromVC.snapshot];
[[transitionContext containerView] addSubview:toVC.view];
[[toVC.navigationController.view superview] insertSubview:fromVC.snapshot belowSubview:toVC.navigationController.view]; // 添加一个半透明的蒙层,展示在 from view 下面
UIView *mask = [[UIView alloc] initWithFrame:bounds];
toVC.navigationController.view.layer.anchorPoint = CGPointMake(0.5, 2.0); mask.backgroundColor = [UIColor colorWithWhite:0 alpha:0.64];
toVC.navigationController.view.frame = bound; mask.alpha = 0;
mask.tag = 100;
toVC.navigationController.view.transform = CGAffineTransformMakeTranslation(0, CGRectGetHeight(bound)); [[transitionContext containerView] addSubview:mask];
[UIView animateWithDuration:duration // 系统不会为我们自动添加 toView,所以我们需要自己添加,以保证 toView 的页面及动画正常展示
delay:0 [[transitionContext containerView] addSubview:toView];
usingSpringWithDamping:1.0
initialSpringVelocity:0 // 先将toView放置在屏幕下边,为下一步的平移动画做准备
options:UIViewAnimationOptionCurveEaseInOut CGRect newFrame = toView.frame;
animations:^{ newFrame.origin.y = CGRectGetHeight(bounds);
fromVC.snapshot.transform = CGAffineTransformMakeTranslation(0, 0); toView.frame = newFrame;
toVC.navigationController.view.transform = CGAffineTransformMakeTranslation(0, 0);
} // 从下到上的平移动画
completion:^(BOOL finished) { [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
fromVC.view.hidden = NO; toView.frame = bounds;
mask.alpha = 1;
} completion:^(BOOL finished) {
[transitionContext completeTransition:YES]; [transitionContext completeTransition:YES];
}]; }];
} }
- (void)pop:(id<UIViewControllerContextTransitioning>)transitionContext { - (void)pop:(id<UIViewControllerContextTransitioning>)transitionContext {
UIViewController * fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController * toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
NSTimeInterval duration = [self transitionDuration:transitionContext];
CGRect bound = [[UIScreen mainScreen] bounds]; CGRect bound = [[UIScreen mainScreen] bounds];
UIView *fromView = [transitionContext viewForKey:UITransitionContextFromViewKey];;
UIView *toView = [transitionContext viewForKey:UITransitionContextToViewKey];
[fromVC.view addSubview:fromVC.snapshot]; // 必须把先前的 mask view 拿出来,显示的标记为 alpha = 1,要不然会发现该蒙层是突然消失
fromVC.navigationController.navigationBar.hidden = YES; // 经常打断点发现,其 alpha 此时为0,所以必须要设置一下 alpha = 1
[[transitionContext containerView] viewWithTag:100].alpha = 1;
// 添加阴影
fromVC.snapshot.layer.shadowColor = [UIColor colorWithRed:0.2 green:0.2 blue:0.2 alpha:0.8].CGColor;
fromVC.snapshot.layer.shadowOffset = CGSizeMake(-3, 0);
fromVC.snapshot.layer.shadowOpacity = 0.5;
fromVC.view.layer.anchorPoint = CGPointMake(0.5, 2.5); //将toView加到toVC.snapshot 的的下面。
fromVC.view.frame = bound; // 不加的话,动画结束后看不到 toView
// 动画过程中看到的是toVC.snapshot
toVC.view.hidden = YES; // 并且需要将 toView放到toVC.snapshot的下面,确保view层级正确
UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
[[transitionContext containerView] addSubview:toVC.view]; [[transitionContext containerView] insertSubview:toView belowSubview:toVC.snapshot];
[[transitionContext containerView] addSubview:toVC.snapshot];
[[transitionContext containerView] sendSubviewToBack:toVC.snapshot]; CGRect newFrame = fromView.frame;
newFrame.origin.y = CGRectGetHeight(bound);
[UIView animateWithDuration:duration [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
delay:0 fromView.frame = newFrame;
usingSpringWithDamping:1.0 [[transitionContext containerView] viewWithTag:100].alpha = 0;
initialSpringVelocity:0 } completion:^(BOOL finished) {
options:UIViewAnimationOptionCurveEaseInOut [[[transitionContext containerView] viewWithTag:100] removeFromSuperview];
animations:^{ // 动画结束后移除toVC.snapshot,留着会挡住toVC,用户无法交互
fromVC.view.transform = CGAffineTransformMakeTranslation(0, CGRectGetHeight(bound));
toVC.snapshot.alpha = 1;
}
completion:^(BOOL finished) {
toVC.navigationController.navigationBar.hidden = NO;
toVC.view.hidden = NO;
[fromVC.snapshot removeFromSuperview];
[toVC.snapshot removeFromSuperview]; [toVC.snapshot removeFromSuperview];
// 需要将toVC.snapshot清空,下一次弹窗时再重新生成 snapshot,确保每一次 snapshot 为最新画面
if (![transitionContext transitionWasCancelled])
{
toVC.snapshot = nil; toVC.snapshot = nil;
}
[transitionContext completeTransition:![transitionContext transitionWasCancelled]]; [transitionContext completeTransition:![transitionContext transitionWasCancelled]];
}]; }];
} }
...@@ -110,14 +93,10 @@ ...@@ -110,14 +93,10 @@
return self.duration; return self.duration;
} }
- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext - (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext {
{ if (self.transitionType == UINavigationControllerOperationPush) {
if (self.transitionType == UINavigationControllerOperationPush)
{
[self push:transitionContext]; [self push:transitionContext];
} } else if (self.transitionType == UINavigationControllerOperationPop) {
else if (self.transitionType == UINavigationControllerOperationPop)
{
[self pop:transitionContext]; [self pop:transitionContext];
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment