今天在github上看了一个自定义present动画的demo,后自己尝试做了一个类似push的动画
自定义PresentViewController实现与push一样的动画,想要实现其他的动画,基本思想差不多
Untitled.gif
1、首先实现PresentViewController动画,新建一个类继承自NSObject,并遵守UIViewControllerAnimatedTransitioning协议
PresentViewController.m文件
#import <Foundation/Foundation.h>
@interface PresentTransitionAnimated : NSObject
@end
PresentViewController.h文件
#import "PresentTransitionAnimated.h"
#import <UIKit/UIKit.h>
@interface PresentTransitionAnimated ()<UIViewControllerAnimatedTransitioning>
@end
@implementation PresentTransitionAnimated
/** 定义动画时间 */
- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext{
return 1.0;
}
/** 定义动画效果 */
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext{
UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
//转场的容器图,动画完成之后会消失
UIView *containerView = [transitionContext containerView];
UIView *fromView = nil;
UIView *toView = nil;
if ([transitionContext respondsToSelector:@selector(viewForKey:)]) {
fromView = [transitionContext viewForKey:UITransitionContextFromViewKey];
toView = [transitionContext viewForKey:UITransitionContextToViewKey];
}else{
fromView = fromViewController.view;
toView = toViewController.view;
}
//对应关系
BOOL isPresent = (toViewController.presentingViewController == fromViewController);
CGRect fromFrame = [transitionContext initialFrameForViewController:fromViewController];
CGRect toFrame = [transitionContext finalFrameForViewController:toViewController];
if (isPresent) {
fromView.frame = fromFrame;
toView.frame = CGRectOffset(toFrame, toFrame.size.width, 0);
[containerView addSubview:toView];
}
NSTimeInterval transitionDuration = [self transitionDuration:transitionContext];
[UIView animateWithDuration:transitionDuration animations:^{
if (isPresent) {
toView.frame = toFrame;
fromView.frame = CGRectOffset(fromFrame, fromFrame.size.width*0.3*-1, 0);
}
} completion:^(BOOL finished) {
BOOL isCancelled = [transitionContext transitionWasCancelled];
if (isCancelled)
[toView removeFromSuperview];
[transitionContext completeTransition:!isCancelled];
}];
}
2、新建控制器ViewController, 并遵守UIViewControllerTransitioningDelegate
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
UIViewController *presentVC = [[UIViewController alloc]init];
presentVC.transitioningDelegate = self;
presentVC.view.backgroundColor = [UIColor redColor];
[self presentViewController:presentVC animated:YES completion:nil];
}
#pragma Mark - UIViewControllerTransitioningDelegate
- (id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source{
return [[PresentTransitionAnimated alloc] init];
}
网友评论