iOS进阶|iOS核心动画CoreAnimation系统进阶(自定义转场动画)
文章图片
想要实现自定义转场动画,需要分两个步骤
一.实现相关协议
@interface CustomTransitionViewController ()
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
self.navigationController.delegate = self;
}
//告诉nav,想自己自定义一个转场
-(id)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC{
if (operation == UINavigationControllerOperationPush) {
WTCircleTransition *trans =[WTCircleTransition new];
return trans;
}
return nil;
}
二.做动画
创建WTCircleTransition协议类
#import
#import @interface WTCircleTransition : NSObject@end
实现UIViewControllerAnimatedTransitioning中的协议
文章图片
WTCircleTransition.m
-(NSTimeInterval)transitionDuration:(id)transitionContext{
return .8f;
}
-(void)animateTransition:(id)transitionContext{
//1.持有transitionContext上下文
_context = transitionContext;
//2.获取view的容器
UIView *containerView = [transitionContext containerView];
//3.初始化toVc,把toVc的view添加到容器view
UIViewController *toVc =[transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
//4.添加动画
/*
拆分动画
4.1 2个圆(大小圆的中心点一致)
4.2 贝塞尔
4.3 蒙版
*/
UIButton *btn;
CustomTransitionViewController * VC1;
SecondViewController * VC2;
if (_isPush) {
VC1 =[transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
VC2 = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
btn = VC1.customTransitionBtn;
}else{
VC2 =[transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
VC1 = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
btn = VC2.backBtn;
}
[containerView addSubview:VC1.view];
[containerView addSubview:VC2.view];
//5.画出小圆
UIBezierPath *smallPath =[UIBezierPath bezierPathWithOvalInRect:btn.frame];
//内切圆
CGPoint centerP;
centerP = btn.center;
//6.求大圆半径 勾股定理
CGFloat radius;
CGFloat y = CGRectGetHeight(toVc.view.bounds)-CGRectGetMaxY(btn.frame)+CGRectGetHeight(btn.bounds)/2;
CGFloat x = CGRectGetWidth(toVc.view.bounds)-CGRectGetMaxX(btn.frame)+CGRectGetWidth(btn.bounds)/2;
if (btn.frame.origin.x >CGRectGetWidth(toVc.view.bounds)/2) {
//位于1,4象限
if (CGRectGetMaxY(btn.frame)< CGRectGetHeight(toVc.view.bounds)/2) {
//第一象限
//sqrtf(求平方根)
radius = sqrtf(btn.center.x *btn.center.x +y*y);
}else{
//第四象限
radius = sqrtf(btn.center.x * btn.center.x + btn.center.y*btn.center.y);
}
}else{
if (CGRectGetMaxY(btn.frame)
#pragma mark - CAAnimationDelegate
-(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{
[_context completeTransition:YES];
//去掉蒙版
if (_isPush) {
UIViewController * toVc =[_context viewControllerForKey:UITransitionContextToViewControllerKey];
toVc.view.layer.mask = nil;
}else{
UIViewController * toVc =[_context viewControllerForKey:UITransitionContextFromViewControllerKey];
toVc.view.layer.mask = nil;
}}
文章图片
大圆半径
文章图片
勾股定理求半径
文章图片
判断象限
在做自定义转场动画时,我们需要进行几个步骤:
- 实现相关协议 push/pop motal segue
- 添加实现了UIViewControllerAnimatedTransitioning的类
- 在类里面实现动画协议,然后添加转场动画
- 告诉上下文,动画完成
实现效果:
文章图片
gitHub代码参考
推荐阅读
- 期刊|期刊 | 国内核心期刊之(北大核心)
- 2020-04-07vue中Axios的封装和API接口的管理
- iOS中的Block
- 推荐系统论文进阶|CTR预估 论文精读(十一)--Deep Interest Evolution Network(DIEN)
- 记录iOS生成分享图片的一些问题,根据UIView生成固定尺寸的分享图片
- 活跃社群的核心标准是什么()
- 2019-08-29|2019-08-29 iOS13适配那点事
- Hacking|Hacking with iOS: SwiftUI Edition - SnowSeeker 项目(一)
- iOS面试题--基础
- VueX--VUE核心插件