首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >自定义转场详解(一)

自定义转场详解(一)

作者头像
Scott_Mr
发布于 2018-05-16 08:39:38
发布于 2018-05-16 08:39:38
1K00
代码可运行
举报
运行总次数:0
代码可运行

前言

本文是我学习了onevcat的这篇转场入门做的一点笔记。

今天我们来实现一个简单的自定义转场,我们先来看看这篇文章将要实现的一个效果图吧:

过程详解

热身准备

我们先创建一个工程,首先用storyboard快速的创建两个控制器,一个作为主控制器,叫ViewController,另外一个作为present出来的控制器,叫PresentViewController,并且用autoLayout快速搭建好界面。就像这样:

我们先做好点击ViewController上面的按钮,present出 PresentViewController,点击PresentViewController上面的按钮,dismiss掉PresentViewController的逻辑。这里有两个注意点:

  1. 因为此处我使用了segue,所以在ViewController按钮点击的时候,我们只需要这样调用就行。 #pragma mark - 点我弹出 -(IBAction)presentBtnClick:(UIButton *)sender { [self performSegueWithIdentifier:@"PresentSegue" sender:nil]; }
  2. 我们平时写dismiss的时候,一般都会是在第二个控制器中直接给self发送dismissViewController的相关方法。在现在的SDK中,如果当前的VC是被显示的话,这个消息会被直接转发到显示它的VC去。但是这并不是一个好的实现,违反了程序设计的哲学,也很容易掉到坑里。所以我们用标准的delegate 方式实现 dismiss

首先我们在PresentViewController控制器中申明一个代理方法。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    #import <UIKit/UIKit.h>
    @class PresentViewController;
    @protocol PresentViewControllerDelegate <NSObject>
    - (void)dismissViewController:(PresentViewController *)viewController;
    @end
    @interface PresentViewController : UIViewController
    @property (nonatomic, weak) id<PresentViewControllerDelegate> delegate;
    @end

在button的点击事件中,让代理去完成关闭当前控制器的工作。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    #pragma mark - 点击关闭
    - (IBAction)closeBtnClick:(UIButton *)sender {
        if (self.delegate && [self.delegate respondsToSelector:@selector(dismissViewController:)]) {
            [self.delegate dismissViewController:self];
        }
    }

与此同时,在ViewController中需要设置PresentViewController的代理,并且实现代理方法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
        if ([segue.identifier isEqualToString:@"PresentSegue"]) {
            PresentViewController *presetVC = segue.destinationViewController;
            presetVC.delegate = self;
        }
    }
    #pragma mark - PresentViewControllerDelegate
    - (void)dismissViewController:(PresentViewController *)viewController {
        [self dismissViewControllerAnimated:YES completion:nil];
    }

OK,到这里,我们一个基本的转场就完成了(这也是系统自带的一个效果)。like this:

主要内容

接下来,要接触我们今天要讲的主要内容了,我们用iOS7中一个新的类UIViewControllerTransitioning来实现自定义转场。


UIViewControllerAnimatedTransitioning

首先我们需要一个实现了协议名为UIViewControllerAnimatedTransitioning的对象。创建一个类叫做PresentAnimation继承于NSObject并且实现了UIViewControllerAnimatedTransitioning协议。(注意:需要导入UIKit框架)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    @interface PresentAnimation : NSObject<UIViewControllerAnimatedTransitioning>

这个协议负责转场的具体内容。开发者在做自定义切换效果时大部门代码会是用来实现这个协议的,这个协议只有两个方法必须要实现的:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    // 返回动画的时间
    - (NSTimeInterval)transitionDuration:(nullable id <UIViewControllerContextTransitioning>)transitionContext;
    // 在进行切换的时候将调用该方法,我们对于切换时的UIView的设置和动画都在这个方法中完成。
    - (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext;

实现这两个方法

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    - (NSTimeInterval)transitionDuration:(nullable id <UIViewControllerContextTransitioning>)transitionContext {
        return 0.8f;
    }
    - (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext {
        // 1.我们需要得到参与切换的两个ViewController的信息,使用context的方法拿到它们的参照;
        UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];   
        // 2.对于要呈现的VC,我们希望它从屏幕下方出现,因此将初始位置设置到屏幕下边缘;
        CGRect finaRect = [transitionContext finalFrameForViewController:toVC];
        toVC.view.frame = CGRectOffset(finaRect, 0, [UIScreen mainScreen].bounds.size.height);
        // 3.将view添加到containerView中;
        [[transitionContext containerView] addSubview:toVC.view];
        // 4.开始动画。这里的动画时间长度和切换时间长度一致。usingSpringWithDamping的UIView动画API是iOS7新加入的,描述了一个模拟弹簧动作的动画曲线;
        [UIView animateWithDuration:[self transitionDuration:transitionContext] delay:0.0 usingSpringWithDamping:0.6 initialSpringVelocity:0.0 options:UIViewAnimationOptionCurveLinear animations:^{
            toVC.view.frame = finaRect;
        } completion:^(BOOL finished) {
            // 5.在动画结束后我们必须向context报告VC切换完成,是否成功。系统在接收到这个消息后,将对VC状态进行维护。
            [transitionContext completeTransition:YES];
        }];
    }

注意点

UITransitionContextToViewControllerKeyUITransitionContextFromViewControllerKey 比如从A present 出B,此时A是FromViewController,B是ToViewController 如果从B dismiss 到A,此时A是ToViewController,B是FromViewController

UIViewControllerTransitioningDelegate

这个接口的作用比较单一,在需要VC切换的时候系统会向实现了这个接口的对象询问是否需要使用自定义转场效果。 所以,一个比较好的地方是直接在主控制器ViewController中实现这个协议。

ViewController中完成如下代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    @interface ViewController ()<PresentViewControllerDelegate,UIViewControllerTransitioningDelegate>
    @property (nonatomic, strong) PresentAnimation *presentAnimation;
    @end
    @implementation ViewController
    #pragma mark - 懒加载
    - (PresentAnimation *)presentAnimation {
        if (!_presentAnimation) {
            _presentAnimation = [[PresentAnimation alloc] init];
        }
        return _presentAnimation;
    }
    #pragma mark - UIViewControllerTransitioningDelegate
    - (id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source {
        return self.presentAnimation;
    }
    - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
        if ([segue.identifier isEqualToString:@"PresentSegue"]) {
            PresentViewController *presetVC = segue.destinationViewController;
            presetVC.delegate = self;
            presetVC.transitioningDelegate = self;
        }
    }

现在看下我们的效果:

相对于上面系统自带的效果来说,我们在present出第二个控制器的时候,带有弹簧效果。

手势驱动百分比切换

现在我们增加一个功能,就是用手势滑动来dismiss,通俗的说,就是让present出来的那个控制器使用手势dismiss。

  1. 创建一个类,继承自UIPercentDrivenInteractiveTransition
  • 我们写一个方法提供给外部类调用。让外部类可以看到传入手势dismiss的VC的入口。

2.既然传入了这个需要手势dismiss的VC,我们就需要保存一下,方便当前类在其他地方使用,所以我们新建一个属性来保存这个传入的VC。

3.和创建PresentAnimation一样,我们创建一个一个DismissAnimation

4.最后,我们在主控制器中添加一个手势驱动的对象,一个dismiss转场的对象,然后懒加载。

完善

此时,我们运行程序,会发现以上代码尽管可以手势驱动了,但是点击按钮dismiss的功能无法使用了。这是因为如果只是返回self.paninterTransition,那么点击按钮dismiss的动画就会失效;如果只是返回nil,那么手势滑动的效果将会失效。综上所述,我们就得分情况考虑。 接下来我们就来完善一下。

ok,到此为止,我们的一个自定义转场动画就算了完成了。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-04-25 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
自定义转场详解(一)
前言 本文是我学习了onevcat的这篇转场入门做的一点笔记。 今天我们来实现一个简单的自定义转场,我们先来看看这篇文章将要实现的一个效果图吧: 过程详解 热身准备 我们先创建一个工程,首先
Scott_Mr
2018/07/05
1.1K0
iOS 自定义转场动画
1、创建一个遵循<UIViewControllerAnimatedTransitioning>协议的动画过渡管理对象,并实现如下两个方法:
且行且珍惜_iOS
2018/05/22
1.2K0
玩转iOS转场动画 原
    关于动画在iOS开发中的应用,曾经整理过一系列的博客进行总结。包括简单的UIView层的动画,CALayer层的动画,Autolayout自动布局动画以及CoreAnimation核心动画框架等。本篇博客主要深入讨论视图控制器、导航控制器来进行界面跳转时的专场动画相关内容。之前的动画相关博客列举如下:
珲少
2018/08/15
1.6K0
玩转iOS转场动画
                                                                            原
【IOS开发基础系列】UIViewController专题
        在UIViewController中,view(黑体的view指的是controller的view属性)有两个循环:加载和卸载循环。当程序的一部分向controller请求view的指针且view不在内存中时,view会进入加载循环,controller会将view加载入内存。
江中散人_Jun
2023/10/16
1.2K0
【IOS开发基础系列】UIViewController专题
iOS_Custom Transition Animation 自定义转场动画
想要在 push 和 pop viewController 时使用自定义的转场动效,需要设置self.naviagtionController.delegate, 并实现UINavigationControllerDelegate的一个方法:
mikimo
2023/10/18
4580
iOS_Custom Transition Animation 自定义转场动画
iOS 自定义 ViewController 过渡动画
WWDC 2013 session 218: Custom Transitions Using View Controllers
Alan Zhang
2018/10/19
1.5K0
iOS UIViewControllerTransitioning 自定义界面跳转动画
UIViewControllerTransitioningDelegate可以控制view controller的出现(presenting) ,消失(dismissing),interacting(交互)动画。
用户3004328
2018/09/06
2.2K0
iOS-可交互滑动的TabBarController
1.先看一下效果 左右滑动交互的TabBarController 2.在iOS7.0以前,要实现这样的效果,只有自定义TabBar了,但这很麻烦。而在iOS7.0以后,苹果在UITabBarContr
用户2215591
2018/06/29
1.9K0
iOS 转场动画探究(一)
什么是转场动画:        转场动画说的直接点就是你常见的界面跳转的时候看到的动画效果,我们比较常见的就是控制器之间的Push和Pop,还有Present和Dismiss的时候设置一下系统给我们的modalTransitionStyle,以及通过手势的左滑或者是右滑的转场等等,这些就是我们比较常见的,当然很大部分APP转场的方式也是我们上面说的常见的。我自己的建议和理解,转场动画能帮你加深理解、总结你对动画的学习,但不要轻易在你的项目中大量的去尝试,还是觉得动画用的好就有点睛之笔的感觉,但若是大量的使用
Mr.RisingSun
2018/01/15
2.9K0
iOS 转场动画探究(一)
iOS-自定义交互式转场动画
自定义转场动画主要有以下步骤 自定义导航栏 自定义交互动画 通过UIPercentDrivenInteractiveTransition协议实现交互 自定义导航栏 自定义导航栏需要遵守<UINavigationControllerDelegate>协议,该协议主要有两个协议方法: // 该方法返回导航跳转时的动画,如果返回nil,则是系统默认的跳转动画,并且通过operation来判断当前执行push还是pop -(id<UIViewControllerAnimatedTransitioning>)navi
用户2215591
2018/06/29
8800
iOS小技能:查看大图浏览器(图片支持滑动切换)
demo视频:https://live.csdn.net/v/embed/157526
公众号iOS逆向
2022/08/22
1.3K0
iOS小技能:查看大图浏览器(图片支持滑动切换)
VCTransitionsLibrary –自定义iOS交互式转场动画的库
本文介绍了一种用于iOS的交互式转场实现方案,通过使用UIKit Dynamics和UIKit Layout实现自定义转场效果。具体实现包括两个部分:一是交互式转场动画的实现,通过CGAffineTransformAnimation结合UIView.animateWithDuration()方法实现;二是交互式转场交互的实现,通过监听UIViewControllerTransitionCoordinator方法实现。该方案适用于界面之间的复杂转场交互场景,可以自定义转场动画和交互逻辑,实现更加顺滑、自然的界面转场效果。
ios122
2018/01/02
1.8K0
关于自定义modal的转场动画
然后在目标控制器中设置遵循UIViewControllerTransitionIngDelegate协议。
老司机Wicky
2018/08/22
1.2K0
关于自定义modal的转场动画
iOS 转场动画探究(二)
这篇文章是接着第一篇写的,要是有同行刚看到的话建议从前面第一篇看,这是第一篇的地址:iOS 转场动画探究(一) 接着上一篇写的内容:        上一篇iOS 转场动画探究(一)我们说到了转场要素的第四点,把那个小实例解释完,这篇还有一点我们接着总结:        Demo的下载地址这里再发一次: 这里是Demo的下载地址 5、  转场协调器协议 UIViewControllerTransitionCoordinator        可以通过需要产生动画效果的视图控制器的transitionCoord
Mr.RisingSun
2018/01/15
1.5K0
iOS 转场动画探究(二)
【iOS】今日头条的转场动画设置+手势控制
最近公司有个需求,做一个今日头条的用户动态的进入和退出的动画效果,并且退场时,可以自己点击退出,也可以手势下滑退出。头条的效果如下:
MapleYe
2020/03/31
1.9K0
【iOS】今日头条的转场动画设置+手势控制
【iOS】教你用ZFPlayer+KTVHTTPCache搭建缓存,预加载的播放器
mgr实现ZFPlayerMediaPlayback协议,然后在初始化时,开启本地服务器
MapleYe
2020/03/31
8.3K7
【iOS】教你用ZFPlayer+KTVHTTPCache搭建缓存,预加载的播放器
抓住iOS的未来 - 30天学习编写30个Swift小程序
=======================================================
nimomeng
2018/09/13
2.7K0
抓住iOS的未来 - 30天学习编写30个Swift小程序
UINavigationController 导航控制器概念属性方法
概念 UINavigationController 继承于 UIViewController 包含:viewcontrollers、NavigationBar、Toolbar 导航控制器是一个堆栈结构,只是其中管理的对象是controller,通过push与pop进行controller的切换,UINavigationController是将这些控件(UINavigationBar,UINavigationItem和UIToolBar)和UIViewController紧密的结合了起来 总结: Naviga
用户2141756
2018/05/18
2.6K0
iOS开发UINavigation系列四——导航控制器UINavigationController
        在前面的博客中,我么你介绍了UINavigationBar,UINavigationItem和UIToolBar,UINavigationController是将这些控件和UIViewController紧密的结合了起来,使用导航,我们的应用程序层次会更加分明,对controller的管理也更加方便。前几篇博客地址如下:
珲少
2018/08/15
2.1K0
iOS开发UINavigation系列四——导航控制器UINavigationController
Mac开发跬步积累(二):NSViewController 转场动画精耕细作
在macOS 10.10之后,关于NSViewController,苹果公司专门在一个extension中提供了四个方法用来处理控制器之间的关系以及切换转场处理.
代码行者
2018/08/23
3K0
Mac开发跬步积累(二):NSViewController 转场动画精耕细作
推荐阅读
相关推荐
自定义转场详解(一)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档