使用Swift编程语言开发iOS应用(三)

连接界面(UI)到代码中

本文中将讲述连接FoodTracker应用的界面元素到程序代码中,定义一些用户能够在界面上执行的动作。

本文的学习目标

  • 解释storyboard中一个scene和底层视图控制器(view controller)之间的关系
  • storyboard上界面元素和源代码之间创建outlet和action的连接
  • 处理用户在文本输入框的输入,在界面上显示结果
  • 设计遵循一个协议的类
  • 理解代理(delegation)模式
  • 根据目标-动作(target-action)模式设计应用的架构

连接界面到源代码

在storyboard中,一个场景(scene)一般代表一个视图控制器(view controller),视图控制器实现了应用程序的行为。一个视图控制器管理着单个内容视图及其具有继承关系的子视图,协调应用程序数据模型(封装了应用的数据)信息的流向并在视图上显示数据,管理内容视图的生命周期,处理设备旋转产生的方向变化,定义应用程序中的界面导航,实现用户输入的响应行为。iOS中所有视图控制器对象都是UIViewController类或其子类。
代码中创建并实现自定义视图控制器的子类,建立类和storyboard中的场景之间的连接,关联代码中的行为到storyboard中的界面。
上一节的项目中,Xcode自动创建了定义ViewController类的swift源代码文件(ViewController.swift),并已连接到storyboard对应的一个视图场景。使用Identity Inspector编辑storyboard上界面元素的对象属性,例如所从属的类。


3_inspector_identity_2x.png
根据界面元素创建Outlets
  1. 打开主storyboard;

  2. 点击右上角的助手编辑器;


    assistant_editor_toggle_2x.png
  3. 在编辑选择栏选中预览ViewController.swift;


    3_switchtoviewcontroller_2x.png
  4. 在ViewController.swift代码中找到类的定义行;

    class ViewController: UIViewController {

  5. 在定义行下面添加MARK注释行;

    // MARK: Properties

带有“// MARK:”开头的注释是一种特殊的注释,用于组织代码和帮助导航到此处代码

  1. 在storyboard界面上选中文本输入框,按住Control键的同时鼠标拖拽至ViewController.swift文件中“// MARK: Properties”代码下面;
    ![Uploading 3_textfield_addoutlet_2x_321850.png . . .]


    3_textfield_dragoutlet_2x.png
  2. 在出现的对话框中Name栏中输入nameTextField;


    3_textfield_addoutlet_2x.png
  3. 点击“Connect”按钮。

    @IBOutlet weak var nameTextField: UITextField!

Xcode将增加一个用于指向文本对话框的相应代码到ViewController.swift文件中,并配置storyboard建立上述连接。
IBOutlet属性通知Xcode从界面编辑器(Interface Builder,前缀缩写IB)中连接到一个叫“nameTextField”的属性,weak关键字表明该属性有可能为nil,这个属性类型为UITextField,其最后的“!”是隐式解包可选类型。

连接标签到ViewController.swift代码中
  1. 选中storyboard中的标签对象,按住Control键的同时鼠标拖拽至ViewController.swift代码文件中声明nameTextField属性的代码下面;


    3_label_dragoutlet_2x.png
  2. 在出现的对话框中Name栏中输入mealNameLabel;


    3_label_addoutlet_2x.png
  3. 点击“Connect”按钮。
    同样,Xcode将增加一个用于指向标签的相应代码到ViewController.swift文件中,并配置storyboard建立上述连接,同文本输入框属性一样,只是属性名称叫“mealNameLabel”,类型是UILabel。

    @IBOutlet weak var mealNameLabel: UILabel!

定义一个要执行的动作(Action)

iOS应用程序是基于事件驱动编程(event-driven programming),即应用程序的执行流向是由事件决定:系统事件和用户动作。用户在界面上执行动作触发应用程序内的事件,这些事件导致应用程序的逻辑执行和数据处理操作,应用程序对用户动作的响应最终反映到界面中。
动作(Action)是一个代码片段,可以连接到出现在应用程序上的某个事件。当该事件发生时,这些代码得到执行。定义一个动作方法完成各种事务,如操作一个数据块或者更新界面等。使用动作响应用户或系统的事件,来驱动应用程序的执行流。创建一个动作类似于创建一个outlet。

创建一个标签重置动作(reset action)
  1. 在ViewController.swift类定义块“}”添加MARK Action注释代码;

    // MARK: Actions

  2. 在storyboard中选中“设置缺省标签文字”按钮,按住Control键的同时鼠标拖拽至MARK Action注释代码下面;


    3_button_dragaction_2x.png
  3. 在出现的对话框中,Connection栏选择Action;
  4. Name栏中输入“setDefaultLabelText”;
  5. Type栏选择UIButton;


    3_button_addaction_2x.png
  6. 点击“Connection”按钮。

Type栏的缺省为AnyObject,Swift语言中AnyObject表明一个可以属于任何类的对象类型。Xcode将增加一段代码到ViewController.swift文件中,并配置动作方法。

> `@IBAction func setDefaultLabelText(sender: UIButton) {
   }`

上面代码中,sender参数指向的对象导致触发了动作,本例是“设置缺省标签文字”按钮。IBAction属性表明本方法是一个从storyboard界面上连接的动作。

代码实现标签重置动作
  1. 在ViewController.swift找到刚才添加的setDefaultLabelText动作方法;
  2. 添加一行代码。

    mealNameLabel.text = "Default Text"

上面完成的例子实现了iOS应用程序设计中的”目标-动作”(target-action)模式,该模式用于当一个指定事件发生时一个对象发送消息到另一个对象。本例中,这个事件是用户点击“设置缺省标签文字”按钮,动作是setDefaultLabelText,目标是ViewController(动作方法所在的类),发送着是“设置缺省标签文字”按钮。”目标-动作”模式中,消息是在代码中定义的一个动作方法,目标(target)是接收消息的对象-能够执行该动作的对象,发送动作消息的对象通常是一个控件(control),例如按钮、滑杆(slider)、切换器(switch)等-触发相应的事件:点击、拖拽或数值改变等。

处理用户输入

当处理接收用户在一个文本输入框的输入时,需要用到文本输入框代理(delegate)的一些帮助。当文本输入框的文本发生变化时或者发生重要事件如用户开始或终止编辑文本,会与其代理进行通信,代理可以使用这些信息在合适的时机保存或清除数据,关闭键盘屏幕等。任何对象作为另外一个对象的代理相当于其遵从适应的协议,一个定义文本输入框代理的协议名为UITextFieldDelegate,本例因为ViewController保持文本输入框的一个引用,将其作为文本输入框的代理,ViewController类采用UITextFieldDelegate协议。

采用UITextFieldDelegate协议
  1. 在ViewController.swift文件中找到class定义行;
  2. 使用”,”符号添加采用UITextFieldDelegate声明。

    class ViewController: UIViewController, UITextFieldDelegate {

设置ViewController为文本输入框nameTextField的代理
  1. 在ViewController.swift文件中找到viewDidLoad()方法;
  2. 在代码行super.viewDidLoad()后面,添加下面代码。

    nameTextField.delegate = self

self关键字引用ViewController类本,ViewController类就成为文本输入框nameTextField的代理。

实现UITextFieldDelegate协议方法

UITextFieldDelegate协议包含选项方法,采用该协议的类可以不提供选项方法的实现,本例为了完成一些行为,提供实现下面两个方法的实现。

func textFieldShouldReturn(textField: UITextField) -> Bool func textFieldDidEndEditing(textField: UITextField)

当用户点击一个文本输入框时,该输入框自动成为一个首响应者(first responder),第一个接收各种类型的应用事件,包括按键事件、移动事件和动作消息等。 文本输入框成为首响应者的一个结果就是,iOS系统会显示键盘小窗口,输入框开始一个编辑事务。当用户想要完成文本输入框的编辑,该输入框需要退出首响应者状态。因此上面两个协议方法的实现,会用于这个情况:用户点击一个按钮来结束文本输入框的编辑,这里用户点击“完成”(Done)或“返回”(Return),协议方法textFieldShouldReturn(_:)会被调用。

实现textFieldShouldReturn方法
  1. 在ViewController.swift文件中"//MARK:Actions"上面添加MARK注释代码如下

    // MARK: UITextFieldDelegate

  2. 在下面输入“func textfieldS”会出现自动完成列表,显示推荐的方法,选择textFieldShouldReturn方法;

    func textFieldShouldReturn(textField: UITextField) -> Bool { }

  3. 在textFieldShouldReturn方法中添加以下代码。

    textField.resignFirstResponder() return true

  4. 完整的代码如下。

    func textFieldShouldReturn(textField: UITextField) -> Bool { textField.resignFirstResponder() return true }

调用UITextField的resignFirstResponder方法退出首响应者状态,返回true表明文本输入框响应用户点击Return按键后关闭键盘小窗口。

实现textFieldDidEndEditing方法

文本输入框退出首响应者状态后,会调用textFieldDidEndEditing协议方法。

  1. 在ViewController.swift文件中,找到textFieldShouldReturn方法;
  2. 在其下面添加以下方法和代码。

func textFieldDidEndEditing(textField: UITextField) { mealNameLabel.text = textField.text }

运行模拟器

3_sim_defaulttext_2x.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容

  • 重要:这是针对于正在开发中的API或技术的预备文档(预发布版本)。苹果提供这份文档的目的是帮助你按照文中描述的方式...
    金_波阅读 3,167评论 6 12
  • 读万卷书不如行万里路,行万里路不如阅人无数
    田理阅读 122评论 0 0
  • 170319@D75.感恩冥想 深深地感恩我拥有的一切!深深地感恩来到我身边的家人们!祝全宇宙众生夜梦吉祥!
    佩诗阅读 187评论 0 0
  • 一、定增法律意见书基本结构 1、发行的主体资格 2、发行是否符合豁免向中国证监会申请核准股票发行的条件...
    哆啦A梦萌萌哒阅读 1,385评论 0 0
  • 今天领导单独开会,可以说是一次深度会议。。。也让我开始意识到自己已处于一个管理者的位置。 作为一个管...
    花言_花语阅读 256评论 1 3