使用 Storyboard Segue 实作 UIViewController 的切换 (实例)
Storyboard 是在 iOS 5 SDK 中才出现的新名词,它其实就是原本的 Xib 档案(Interface Builder),用来制作介面排版方面的工具,当然在 Storyboard 里也多了很多应用的元件,其中 Storyboard Segue 可以让你几乎连程式码都不用写,就轻松完成两个 UIViewController 的切换工作,以下是我们的示范。
首先在开啓新专案时选择 Single View Application 来简化流程,可以少制作一个 UIViewController 与它对应的 class 档,如果各位有需要当然也可以开啓完全空白的干净的新专案,再自行加入 storyboard 与 UIViewController。
接着来到专案下的 storyboard 画面,从右下方的元件库中拉一个 UIViewController 到 storyboard 中,并且分别对两个 UIViewController 做介面上的设计:增加 Navigation Bar 来辨识彼此,与一个用来做页面切换按钮,如下图。
我们希望在页面 1 按下前往页面 2 的按钮时,画面能切换至页面 2,之后也能以同样的方法返回页面 1,为了达到目的,必须使用 Storyboard Segue 元件将两个 UIViewController,给连起来,由于 Storyboard Segue 是动态产生的,所以并不会出现在元件 Storyboard 的元件库中。
产生 Storyboard Segue 的方法常简单,就如同替介面元件和程式码做连结的拖曳方式一样的直觉,使用滑鼠右键将页面 1 内的按钮拖曳连结至页面 2 ,并选择 Model 做连结,Storyboard Segue 就会自动连结两个 UIViewController,如下图。
现在你可以用模拟器执行看看,在 Segue DEMO 页面 1 按下前往页面 2 的按钮时,画面就会切换至页面 2,如果想要使用不同的换页效果,可以在 Storyboard Segue 中的 Transition 属性做修改,范例中所使用的是翻页 Partial Curl 效果。
下来就是从页面 2 「返回」页面一,在这里我们特别强调「返回」而不是前往,一个错误的做法,是按照上面的步骤将页面 2 的按钮拖曳连结至页面一的 Model,使整个 Storyboard 的佈局如下图。
如果你按照这样的设计方式来执行,你会发现两个页面的确可以互相切换,功能上是正确,但是背后的意义却大不相同,而且在多次切换后很有可能创造过多的 UIViewController 实体,这样做画面每次都会朝同样的方向来做切换的效果,每次都会建立一个新的 UIViewController 实体来使用。
我想大家应该都猜到正确的做法应该是在页面 2 的程式码中使用 dismissModalViewControllerAnimated: 方法,或是 dismissViewControllerAnimated:completion: 方法来解散页面 2,并返回先前的页面。
替专案新增一个 UIViewController 的 Subclass,我们命名为 Page2ViewController,并取消 With XIB for user interface(我们已经建立了它的介面),接着在其中实作一个按钮事件来解散页面,程式码如下。
- (IBAction)returnToFirstPage:(id)sender {[self dismissViewControllerAnimated:YES completion:^{}];}
最后回到专案下的 Storyboard,将我们新产生的 UIViewController 与 Page2ViewController 做连结,连结的方式是在 UIViewController 的属性中选择对应的 class 档,如下图,之后将其按钮元件与 Page2ViewController 的按钮事件做连结即可。
现在再用模拟器执行看看,按下页面 2 中的按钮,画面会以相反的方向的切换效果来返回页面 1。
我们已经成功建立两个可以互相切换的 UIViewController,一个是透过 Storyboard Segue 来切换,另一个则是使用 dismissViewControllerAnimated: 的方法来返回先前的 UIViewController,接下来就是要解决两个 UIViewController 之间传值的问题,这里同样提供两个方法,在页面 1 的部份同样使用 Storyboard Segue 来帮助我们传递资讯给页面 2,而在页面 2 的部份,则是使用老方法,透过代理委托 delegate 的方式来传送资讯。
首先我们在两个 UIViewController 分别拉一个 UITextField 元件,并将此元件与 class 做连结,分别命名为 page1TextField 与 page2TextField,连结的方式可以参考从使用 UIButton 说 Hello 开始说起(上)ㄧ文,如果是使用 Xcode 4 的朋友也可以直接参考 Xcode 4 的 Assistant Editor 关联编辑功能ㄧ文,节省撰写程式码的时间。
在透过 Storyboard Segue 传值的部份,我们必须在页面 2 的 UIViewController class 里设置一个 NSString 的变数,它的目的是用来接收由页面 1 透过 Storyboard Segue 所传过来的资讯,程式码如下。
@property (weak) NSString *string;//别忘了在对应的实作档中加入@synthesize string;
之后在 viewDidLoad 的函式里我们将 string 的值指定给 page2TextField,这个动作会让页面 2 的画面在被开啓时就会把 page2TextField 的内容设成 Storyboard Segue 所传送过来的值。
- (void)viewDidLoad{[super viewDidLoad];page2TextField.text = string;}
接着回到页面 1 的 UIViewController class 里,新增一个内建的函式如下,就完成透过 Storyboard Segue 传值的方法。
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {//将page2设定成Storyboard Segue的目标UIViewControllerid page2 = segue.destinationViewController;//将值透过Storyboard Segue带给页面2的string变数[page2 setValue:page1TextField.text forKey:@"string"];}
另一个方法就是使用代理委托 delegate 的方法,透过建立一个协定 @protocol 的方式,让其它的採纳此协定的 class 可以实作协定内的函式,我们在页面 2 的 UIViewController class 里设置一个协定,并且在页面 1 的 UIViewController class 里实作协定里的方法,让程式执行到页面 2 时,仍然能够取得页面 1 的实例 Instance,进而使用协定里的方法来设定 page2TextField 的数值。
首先来到页面 2 的 UIViewController class,建立一个协定 Page2Delegate,并且定义其内部的方法 passValue:,接着宣告一个採用此协定的物件 delegate,其程式码如下。
#import <UIKit/UIKit.h>//建立一个协定@protocol Page2Delegate//协定中的方法- (void)passValue:(NSString *)value;@end@interface Page2ViewController : UIViewController@property (weak, nonatomic) IBOutlet UITextField *page2TextField;@property (weak) NSString *string; //宣告一个採用Page2Delegate协定的物件@property (weak) id delegate;@end
接下来就是决定协定中的方法要在什么时候生效,也就是要在什么地方呼叫 passValue: 方法函式,而此函式会在採用此协定的类别 Class 中被实作。回顾程式的需求,我们希望在页面 2 按下返回页面 1 的按钮时,能将 page2TextField 的数值传给页面 1 的 page1TextField,所以呼叫协定 passValue: 方法的程式码,势必要写在此按钮事件中。
- (IBAction)returnToFirstPage:(id)sender {[self dismissViewControllerAnimated:YES completion:^{}];//呼叫协定中的方法并带入page2textField的数值[delegate passValue:page2TextField.text];}
现在,当我们按下页面 2 的按钮时,就会呼叫採用 Page2Delegate 协定的 class,而此 class 必须要实作此协定内的方法,所以回到页面 1 的 UIViewController class,我们要替此 class 採用 Page2Delegate 的协定,并且实作协定内的 passValue: 方法函式。
採用协定的方式是在 @interface 区段的地方加上 <协定名称> 的程式码,由于此协定是写在别的 class 中,所以在採用协定之前别忘了先引用它,以下是页面 1 的 UIViewController class .h 标头档。
#import <UIKit/UIKit.h>//引用持有Page2Delegate协定的class#import "Page2ViewController.h"@interface MLViewController : UIViewController //採用协定@property (weak, nonatomic) IBOutlet UITextField *page1TextField;@end
接着在 .m 实作档中实作协定内的 passValue: 方法函式。
- (void)passValue:(NSString *)value {//设定page1TextField为所取的的数值page1TextField.text = value;}
最后一个步骤,也就是大家常常会忘记的,要将代理 delegate 设成自己(页面 1 的 UIViewController),也就是大家在使用协定时最常写的一行程式码 object. delegate = self(object 指的就是页面 2 的 UIViewController),至于这行程式码要写在哪里?还记得之前透过 Storyboard Segue 传值的部份,我们已经藉由内建的函式取得页面 2 的 UIViewController 实例 page2,所以我们修改此内建函式,利用 page2 来设定 delegate 变数。
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {//将page2设定成Storyboard Segue的目标UIViewControllerid page2 = segue.destinationViewController;//将值透过Storyboard Segue带给页面2的string变数[page2 setValue:page1TextField.text forKey:@"string"];//将delegate设成自己(指定自己为代理)[page2 setValue:self forKey:@"delegate"];}
如果忽略此步骤,页面 2 里的 delegate 参数在呼叫 passValue 方法时,并不会知道是谁(哪个 class)实作了它的方法,因此参数也无法由页面 2 传递至页面 1。
ps:如果你对于解散 UITextField 的小键盘有问题,可以参考UITextField 输入结束后的收起小键盘的方式ㄧ文。
来源:http://furnacedigital.blogspot.com/2011/12/storyboard-segue-uiviewcontroller.html
使用 Storyboard Segue 实作 UIViewController 的切换 (实例)相关推荐
- html图片多tab切换代码,CSS实现Tab页切换实例代码
1.hover 移入其父元素.navI时,触发鼠标的hover态,给父元素添加样式为position:relative;z-index:1;.从而提升了层级z-index.在其子元素导航内容的层级比拼 ...
- Vue-图片切换实例
Vue-图片切换实例 核心代码 实例比较简单,对左箭头与右箭头绑定点击事件,实现img数组遍历.注意的是:首张图片与最后一张图片进行判断隐藏显示. 核心代码 <div id="mask ...
- hikari如何切换数据源_spring boot+mybatis 多数据源切换(实例讲解)
由于公司业务划分了多个数据库,开发一个项目会同事调用多个库,经过学习我们采用了注解+aop的方式实现的 1.首先定义一个注解类 @Retention(RetentionPolicy.RUNTIME) ...
- UIVIewController自定义切换效果-b
之前介绍动画时提过UIView的转场动画,但是开发中我们碰到更多的viewController的切换,ios中常见的viewcontroller切换有四种:模态视图,导航栏控制器,UITabBarCo ...
- 一个全屏页面切换实例
这里写了一个全屏切换的实例,纯手工,没有使用任何插件~ <!DOCTYPE html> <html lang="zh-CN"> <head> & ...
- Java Web的Struts2的多语种网站的多语言切换实例
先看图图: 图1: 图2: 图3: 图4: 一 首先下载Properties Editor插件,该插件是支持中文的资源文件编辑器:MyEclipse 10.6 以上不用安装该插件,使用自带资源文件编辑 ...
- oracle 多个实例互相切换实例
oracle的sqlplus命令是通过环境变量ORACLE_SID的值来确定连接实例. 如需要连接实例a,则设置ORACLE_SID=a 如需要连接实例b,则设置ORACLE_SID=b set OR ...
- MFC CPropertySheet 多页面切换 实例
为了能实现在同一个页面实现多个页面的切换效果.CPropertySheet要与CPropertyPage一起使用. 首先 新建一个MFC工程--MFC AppWizard(exe), 取名Pa ...
- html tab与jQuery,使用jquery实现div的tab切换实例代码
jQuery实现Tab切换 接触jQ不久以前的js代码来写的简单效果现在用jQ来写: HTML代码: 最新评论近期热评随机文章 1234567890-1 1234567890-2 1234567890 ...
最新文章
- linux一键安装包
- Verilog中的逻辑运算符与按位运算符的区分
- 获取crm服务器信息失败,无法连接到 Dynamics CRM 服务器,因为凭据身份验证 - Dynamics 365 Sales | Microsoft Docs...
- 狼羊菜过河问题深入学习分析——Java语言描述版
- 成功解决VMware虚拟机中的please remove the installation medium then press enter
- android 自动表单提交数据,Android 使用三种方式获取网页(通过Post,Get进行表单的提交)...
- 数据可视化(三)- Seaborn简易入门
- 在电路设计中,这7个接口类型太重要了,我难道不该学学么!
- JAVA编程心得-JAVA实现CRC-CCITT(XMODEM)算法
- timeval的时间转换成毫秒之后多大的数据类型可以装下
- oracle+行换列,Oracle的数据表中行转列与列转行的操作实例讲解
- React简介、虚拟DOM、Diff算法、创建React项目、JSX语法、组件、组件声明方式、组件传值props和state、组件的生命周期
- python爬虫程序的流程图_Python即时网络爬虫项目: 内容提取器的定义(Python2.7版本)...
- 树堆(Treap)图文详解与实现
- CSS使图像等比例缩放兼容IE6、IE7、FF
- 紧急通知:阿里聚合直播盒子APP源码2019年5月以前的版本BUG
- Win7扫雷的H5完整复刻实现(一) / js扫雷算法的初次鉴定与地图初始化实现
- 计算机无法同步,win7系统电脑无法同步时间的解决方法
- java 错误 找不到符号_java错误:找不到符号
- 判断中心对称图形C语言
热门文章
- 折线分割平面(HDU-2050)
- 输出第二个整数(信息学奥赛一本通-T1002)
- 信息学奥赛C++语言:素数的判定
- 40 WM配置-作业-确认(转储单TO确认)
- url带多个参数_动态URL和静态URL做seo优化不必二选一
- 以独占方式锁定此配置文件失败.另一个正在运行_加速用例执行最有效的方法,手把手教你如何并行地运行自动化测试...
- 运算均值方差_Python数据分析之NumPy(运算篇)
- COCO数据集提取自己需要的类,转VOC
- MongoDB入门 - 安装教程
- Bootstrap圣诞节主题商城网站模板