八、UIViewController们之间的协作——Segue
概述
正所谓“一生二,二生三,三生万物”,1个UIViewController没什么花样,多个UIViewController相互协作就有了各式各样丰富多彩的APP。但是UIViewController们自成一体互不认识,整天就只知道在自己的界面里码代码,该怎么让他们配对成功呢?这时候就需要我们的介绍人——Segue——登场了。首先我们会介绍UIViewController是如何通过Segue暗送秋波,Segue共分为5类:show,show detail,present modally,present as popover和custom(另有push和modally两类,因被xcode弃用,所以此处不表)。
传递参数
现在我们要再创建1个UIViewController,并且让初始UIViewController可以传递1个字符串到第2个UIViewController。
首先,创建1个新工程,然后在Main.storyboard上再拖入1个UIViewController。
然后再创建1个UIViewController所对应的类文件,我们将其命名为SecondViewController。
然后我们将SecondViewController和Storyboard上的UIViewController关联起来:选中第2个UIViewController,将其Class属性设置为SecondViewController。
“control-拖拽”初始UIViewController的“铜钱状”图标到第2个UIViewController上,并选择“Show”。
于是我们创建了我们的第1个Segue,就是在两个UIViewController面板之间那条带箭头的线。那我们如何在代码中引用这个Segue呢?Segue不像Label或者button,它是无法通过“controller-拖拽”的方式来引用的,但是可以通过索引Segue的Identifier来引用Segue。在Storyboard上选中Segue那条线,然后修改“Identifier属性”为“MySegue”。
接着,我们在第一个UIViewController添加1个触发Segue的Button,并为其添加触发Segue的代码,其中performSegue的参数“withIdentifier”用于确定segue的Identifier,从而确定触发哪一个Segue。
到目前为止,Segue确实可以触发了,但是两个UIViewController之间还没有产生数据交互。
我们先加入1个内嵌的导航栏,并命名其标题为SegueTest
我们在SecondViewController中添加1个字符串作为其导航栏的标题。
现在我们要在触发Segue时,向SecondViewController中传入1个字符串作为其导航栏的title。
大功告成。
Segue的类型
开头我们就介绍了,segue有show,show detail,present modally,present as popover和custom共5种类型,那它们之间有什么区别呢?
在刚刚的例子中,我们发现在触发Segue进入SecondViewController后,导航栏自动添加了1个回退键(内嵌导航栏真贴心~)
这就是“show segue”的特点:在进入新的UIViewController时,新的UIViewController会保留前一个UIViewController的内嵌导航栏,并且提供返回按键。
那如果我把“show segue”换成“show detail segue”呢?
我们再新建1个工程,基本复制前一个例子,唯独把“show segue”换成“show detail segue”。我们来看看效果:
千万不要说:“居然没有效果?!”
因为效果很明显:导航栏没了!
这就是“show detail segue”的特点:在进入新的UIViewController时,新的UIViewController不在使用前一个UIViewController的内嵌导航栏,更不会提供返回键。
于是我们给SecondViewController单独添加导航栏:选中SecondViewController的面板再依次选择Editor->Embeded in->Navigation Controller。
这时需要注意,“MySegue”的关系改变了,它不再是“ViewController->SecondViewController”的关系,而是“ViewController->SecondViewController的导航栏”的关系。所以我们要做如下代码修改,否则运行会崩溃。
同时再添加1个返回按键
这时有个问题,那就是ViewController无法将数据直接交给SecondViewController,而是必须将数据先交给SecondViewController的NavigationController,我们可以重新定义1个SecondNavigationController并继承UINavigationController,然后将SecondViewController的NavigationController的class设置成SecondNavigationController。我们在SecondNavigationController中预设我们想要传递的数据,ViewController将数据传递给SecondNavigationController后SecondViewController就可以通过navigationController成员变量获取数据,此处不再举例。
“present modally”的特点:和“show detail”基本相同,但是多一些动画效果。
“present as popover”的特点:常用于菜单弹框。
老样子,第一步先Control拖拽1个Segue,并选择Segue as popover。
我们在第2个UIViewController添加2个按钮“唧唧”和“喳喳”。然后选中Segue,设置其“Identifier”为“MySegue”,将“Anchor”拖拽到第1个UIViewController上的Button上。
修改UIViewController的代码,添加“UIPopoverPresentationControllerDelegate”代理,并重写“adaptivePresentationStyle”函数,并在prepare中将代理设置给Segue,同时添加第1个UIViewController中按钮的事件触发代码(actionTriggerSegue)
看看效果:感觉弹框略大了些,而且还把Button给遮住了。
选中第2个ViewController,并设置其“Content Size”。
Xcode上的模拟效果似乎没什么变化。我们再修改模拟的大小,这样弹框的尺寸就变小了。
然后我们要希望弹框不要遮住“Button”,于是我们让“Button”位于弹框右侧。
如果你还想要一些更炫酷的过场动画,那么你可以使用“Custom”Segue。
“Custom”的特点:多用于自定义过场动画。
首先,自定义1个Segue,我们此处命名其为“CustomSegue”
重写“perform”函数,其中srcView和dstView分别为Segue切换时,切换前的ViewController和切换后的ViewController,我们为dstView添加3种动画:
旋转动画、X轴放大动画和Y轴放大动画。
Control拖拽Segue,使用Custom类型,然后设置“Identifier”为“MySegue”,并将Class设置为“CustomSegue”
最后别忘记给按钮添加触发Segue的事件
源码下载(Show Segue):https://pan.baidu.com/s/1qTugv5cWriVg4kx5vZTxHg
源码下载(Show Detail Segue):https://pan.baidu.com/s/1rL2J_uxe4xMJcJatbG-niA
源码下载(Present Modally Segue):https://pan.baidu.com/s/1qemWf7n9vfSgLz0v6d6HNA
源码下载(Present as popover Segue):https://pan.baidu.com/s/1DzpXJnLPmHlfvTNqTiJYlg
源码下载(Custom Segue):https://pan.baidu.com/s/1E7A__CamnJz-BFhhlS_tZg
八、UIViewController们之间的协作——Segue的更多相关文章
- java多线程(七)-线程之间的 协作
对于多线程之间的共享受限资源,我们是通过锁(互斥)的方式来进行保护的,从而避免发生受限资源被多个线程同时访问的问题.那么线程之间既然有互斥,那么也会有协作.线程之间的协作也是必不可少的,比如 盖个商场 ...
- Java并发编程,互斥同步和线程之间的协作
互斥同步和线程之间的协作 互斥同步 Java 提供了两种锁机制来控制多个线程对共享资源的互斥访问,第一个是 JVM 实现的 synchronized,而另一个是 JDK 实现的 ReentrantLo ...
- Java多线程——线程之间的协作
Java多线程——线程之间的协作 摘要:本文主要学习多线程之间是如何协作的,以及如何使用wait()方法与notify()/notifyAll()方法. 部分内容来自以下博客: https://www ...
- java并发系列(二)-----线程之间的协作(wait、notify、join、CountDownLatch、CyclicBarrier)
在java中,线程之间的切换是由操作系统说了算的,操作系统会给每个线程分配一个时间片,在时间片到期之后,线程让出cpu资源,由其他线程一起抢夺,那么如果开发想自己去在一定程度上(因为没办法100%控制 ...
- JS多异步之间的协作方案
场景:使用工具函数downloadAllAsync接收一个URL数组并下载所有文件,结果返回一个存储了文件内容的数组,每个URL对应一个字符串. 好处:downloadAllAsync并不只有清理嵌套 ...
- kubernets之控制器之间的协作以及网络
一 创建一个deployment的时候整个kubernets集群的资源和事件的调用链 1.1 创建一个deployment的资源,在提交的时候,集群中的调度器,控制器以及node节点上kubele ...
- python3--多目录之间的协作的一些必备知识
# Auther: Aaron Fan # 动态获取执行文件的相对路径路径:print(__file__) #动态获取执行文件的绝对路径:import osfile_path = os.path.ab ...
- java 线程之间的协作 wait()与notifyAll()
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGlhbmdydWkxOTg4/font/5a6L5L2T/fontsize/400/fill/I0JBQk ...
- Rails、Nginx、Passenger、bundle之间的协作关系
引自:http://www.zhihu.com/question/20062163 Bundle是Gem包的依赖管理工具,RubyGem本身有依赖管理为何还要Bundle呢?有时候两个gem虽然都依赖 ...
随机推荐
- 【Linux】解决"no member named 'max_align_t'
编译遇到错误: /usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.1/../../../../include/c++/5.4.1/cstddef:51:11: erro ...
- Ubuntu安装cuda
到官网选择对应的cuda版本.cuda跟显卡的驱动是有个依赖关系的.参见这篇博客 然后按照提示,运行按照程序 sudo sh cuda_10..130_410.48_linux.run 然后安装完成后 ...
- [转]Go语言中的make和new
前言 本文主要给大家介绍了Go语言中函数new与make的使用和区别,关于Go语言中new和make是内建的两个函数,主要用来创建分配类型内存.在我们定义生成变量的时候,可能会觉得有点迷惑,其实他们的 ...
- Windows server 2008普通用户不能远程登录问题
1.查登录权限 如果文件服务器没有为用户授权,那么用户自然就不能远程登录服务器系统了,为此笔者决定先仔细检查一下文件服务器系统是否为自己使用的登录账号,授予了远程登录权限.在进行这种检查时,笔者先是在 ...
- mongo连接拒绝10061原因
首先检查Mongo是否启动: 启动 再次检查mongo配置文件是否允许其他人访问,默认路由是否加上 .进入mongodb安装目录的bin目录,新增mongodb.conf文件,输入 bind_ip=0 ...
- dedecms wap 上一篇 下一篇 链接出错
打开 \include\arc.archives.class.php 文件 大约在839 行,查找 $mlink = 'view.php?aid='.$preRow['id']; 修改 ...
- Internet Explorer 已限制此网页运行脚本或ActiveX控件。 允许阻止的内容(A)
打开“Internet选项”->"高级",勾选"允许活动内容在“我的电脑”的文件中运行".重启IE
- [原] MyBatis 整理
花了一上午的时间,先整理一个脑图.
- UCloud 的安全秘钥 (计蒜客初赛第五场)(待解决)
20.7% 1200ms 262144K 每个 UCloud 用户会构造一个由数字序列组成的秘钥,用于对服务器进行各种操作.作为一家安全可信的云计算平台,秘钥的安全性至关重要.因此,UCloud 每年 ...
- hibernate03增删改查
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hiber ...