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

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

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