iOS-自定义模态跳转的运用
来源:互联网 发布:javaweb书籍推荐知乎 编辑:程序博客网 时间:2024/04/27 08:10
iOS开发中,常见界面之间的跳转方式有:
- 1-改变window的根视图;
- 2-模态跳转(present/dismiss);
- 3-导航控制器的push(show)和pop.
但在实际开发中,以上三种界面跳转的方式无法满足我们的需求时,需要我们DIY,然后自定义模态跳转就起作用了.
下面通过写一个Demo来展示自定义模态跳转(Demo传送门在最后)
- 利用UIPageViewController实现卡片是分页滚动
- 自定义视图的模态跳转
1-present跳转核心代码
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext { // 容器视图 UIView *containerView = [transitionContext containerView]; // 当前控制器 UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey]; // 目标控制器 UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey]; // 初始大小 CGRect initialFrame = self.originFrame; // 最终大小 CGRect finalFrame = [transitionContext finalFrameForViewController:toVC]; // 目标控制器截屏(初始化之后的) UIImageView *snapshot = [AnimationHelper getImage:toVC.view]; // 设置目标控制器的初始大小 snapshot.frame = initialFrame; // 切圆角 snapshot.layer.cornerRadius = 25; snapshot.layer.masksToBounds = YES; // 添加到容器视图中 [containerView addSubview:toVC.view]; [containerView addSubview:snapshot]; // 隐藏目标控制器视图 toVC.view.hidden = YES; // 设置动画属性 [AnimationHelper perspectiveTransformForContainerView:containerView]; // 默认让目标视图的截图 Y 轴 旋转180度 snapshot.layer.transform = [AnimationHelper yRotation:M_PI_2]; // 获取时间间隔 CGFloat duration = [self transitionDuration:transitionContext]; // 1 定义 关键帧动画 [UIView animateKeyframesWithDuration:duration delay:0 options:UIViewKeyframeAnimationOptionCalculationModeCubic animations:^{ // 2 添加关键帧动画1 - 让主控制器旋转 180 度 snapshot.layer.transform = [AnimationHelper yRotation:M_PI_2]; [UIView addKeyframeWithRelativeStartTime:0.0 relativeDuration:0.33 animations:^{ fromVC.view.layer.transform = [AnimationHelper yRotation:-M_PI_2]; }]; // 3 添加关键帧动画2 - 切换目标控制器的动画,让目标控制器截图旋转180度展示出来 [UIView addKeyframeWithRelativeStartTime:0.33 relativeDuration:0.33 animations:^{ snapshot.layer.transform = [AnimationHelper yRotation:0.0]; }]; // 4 添加关键帧动画3 - 设置目标控制器截屏的大小为最终屏幕 [UIView addKeyframeWithRelativeStartTime:0.66 relativeDuration:0.33 animations:^{ snapshot.frame = finalFrame; }]; } completion:^(BOOL finished) { // 显示目标控制器 toVC.view.hidden = NO; // 恢复根控制器的 transform 为初始状态 fromVC.view.layer.transform = [AnimationHelper yRotation:0.0]; // 移除截屏 [snapshot removeFromSuperview]; // 完成 模态跳转动画 [transitionContext completeTransition:![transitionContext transitionWasCancelled]]; }];}
2-dismiss跳转核心代码
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext { // 容器视图 UIView *containerView = [transitionContext containerView]; // 当前控制器 UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey]; // 目标控制器 UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey]; // 最终大小 CGRect finialFrame = self.destinationFrame; // 根控制器截屏(初始化之后的) UIImageView *snapshot = [AnimationHelper getImage:fromVC.view]; // 切圆角 snapshot.layer.cornerRadius = 25; snapshot.layer.masksToBounds = YES; // 添加到容器视图中 [containerView addSubview:toVC.view]; [containerView addSubview:snapshot]; // 隐藏根控制器视图 fromVC.view.hidden = YES; // 设置动画属性 [AnimationHelper perspectiveTransformForContainerView:containerView]; // 默认让目标视图的截图 Y 轴 旋转180度 toVC.view.layer.transform = [AnimationHelper yRotation:-M_PI_2]; // 获取时间间隔 CGFloat duration = [self transitionDuration:transitionContext]; // 1 定义 关键帧动画 [UIView animateKeyframesWithDuration:duration delay:0 options:UIViewKeyframeAnimationOptionCalculationModeCubic animations:^{ // 2 添加关键帧动画1 - 设置根控制器截屏的大小为最终大小 [UIView addKeyframeWithRelativeStartTime:0.0 relativeDuration:0.33 animations:^{ snapshot.frame = finialFrame; }]; // 3 添加关键帧动画2 - 设置根控制器截屏旋转180度隐藏 [UIView addKeyframeWithRelativeStartTime:0.33 relativeDuration:0.33 animations:^{ snapshot.layer.transform = [AnimationHelper yRotation:M_PI_2]; }]; // 4 添加关键帧动画1 - 让目标控制器旋转 180 度 展示出来 [UIView addKeyframeWithRelativeStartTime:0.66 relativeDuration:0.33 animations:^{ toVC.view.layer.transform = [AnimationHelper yRotation:0.0]; }]; } completion:^(BOOL finished) { // 显示目标控制器 fromVC.view.hidden = false; // 移除截屏 [snapshot removeFromSuperview]; // 完成 模态跳转动画 [transitionContext completeTransition:![transitionContext transitionWasCancelled]]; }];}
3-跳需要模态跳转的控制器中接受代理
#pragma mark --------------------关键代码 // 设置模态跳转的代理方法 revealVC.transitioningDelegate = self; // 设置需要手势的控制器 [self.swipeInteractionController wireToViewController:revealVC];#pragma mark --------------------关键代码 [self showViewController:revealVC sender:nil];
4-实现UIViewControllerTransitioningDelegate代理方法
- (nullable id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source { self.flipPresentAnimationController.originFrame = self.cardView.frame; return self.flipPresentAnimationController;}- (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed { self.flipDismissAnimationController.destinationFrame = self.cardView.frame; return self.flipDismissAnimationController;}- (id<UIViewControllerInteractiveTransitioning>)interactionControllerForDismissal:(id<UIViewControllerAnimatedTransitioning>)animator { return self.swipeInteractionController.interactionInProgress ? self.swipeInteractionController : nil;}
Demo的传送门:
OC版地址
Swift版地址
0 0
- iOS-自定义模态跳转的运用
- 自定义模态跳转
- iOS自定义转场动画(3)——自定义模态跳转之Present
- iOS 自定义界面跳转动画
- iOS使用自定义URL实现控制器之间的跳转
- iOS使用自定义URL实现控制器之间的跳转
- iOS使用自定义URL实现控制器之间的跳转
- iOS自定义转场动画(4)——自定义模态跳转之dismiss与手势驱动
- IOS runtime的运用
- ios GCD的运用
- IOS 多线程的运用
- iOS枚举的运用
- ios ViewController生命周期 ---- push跳转和模态跳转的VC生命周期
- 运用js跳转页面的几个实例
- Android 自定义VIEW的运用
- CoordinatorLayout自定义Behavior的运用
- 自定义view的基本运用
- iOS开发--iOS使用自定义URL实现控制器之间的跳转(DCURLRouter组件)
- typeof
- python列表生成式
- 几个冷门的前端小知识
- Duilib 弹出子对话框
- SecureCRT上传-bash: rz: command not found
- iOS-自定义模态跳转的运用
- 一维卷积积分学习实例
- 【Linux】命名管道FIFO
- spring cache相关注解介绍 @Cacheable、@CachePut、@CacheEvict
- des加密算法
- css基本属性
- ffmpeg 常用基本命令和ffmpeg处理RTMP流媒体的常用命令
- 软件测试流程(二)
- arm neon RGB转Gray的例子