使用Swift編程語(yǔ)言開(kāi)發(fā)iOS應(yīng)用(三)

連接界面(UI)到代碼中

本文中將講述連接FoodTracker應(yīng)用的界面元素到程序代碼中,定義一些用戶能夠在界面上執(zhí)行的動(dòng)作。

本文的學(xué)習(xí)目標(biāo)

  • 解釋storyboard中一個(gè)scene和底層視圖控制器(view controller)之間的關(guān)系
  • storyboard上界面元素和源代碼之間創(chuàng)建outlet和action的連接
  • 處理用戶在文本輸入框的輸入,在界面上顯示結(jié)果
  • 設(shè)計(jì)遵循一個(gè)協(xié)議的類
  • 理解代理(delegation)模式
  • 根據(jù)目標(biāo)-動(dòng)作(target-action)模式設(shè)計(jì)應(yīng)用的架構(gòu)

連接界面到源代碼

在storyboard中,一個(gè)場(chǎng)景(scene)一般代表一個(gè)視圖控制器(view controller),視圖控制器實(shí)現(xiàn)了應(yīng)用程序的行為。一個(gè)視圖控制器管理著單個(gè)內(nèi)容視圖及其具有繼承關(guān)系的子視圖,協(xié)調(diào)應(yīng)用程序數(shù)據(jù)模型(封裝了應(yīng)用的數(shù)據(jù))信息的流向并在視圖上顯示數(shù)據(jù),管理內(nèi)容視圖的生命周期,處理設(shè)備旋轉(zhuǎn)產(chǎn)生的方向變化,定義應(yīng)用程序中的界面導(dǎo)航,實(shí)現(xiàn)用戶輸入的響應(yīng)行為。iOS中所有視圖控制器對(duì)象都是UIViewController類或其子類。
代碼中創(chuàng)建并實(shí)現(xiàn)自定義視圖控制器的子類,建立類和storyboard中的場(chǎng)景之間的連接,關(guān)聯(lián)代碼中的行為到storyboard中的界面。
上一節(jié)的項(xiàng)目中,Xcode自動(dòng)創(chuàng)建了定義ViewController類的swift源代碼文件(ViewController.swift),并已連接到storyboard對(duì)應(yīng)的一個(gè)視圖場(chǎng)景。使用Identity Inspector編輯storyboard上界面元素的對(duì)象屬性,例如所從屬的類。


3_inspector_identity_2x.png
根據(jù)界面元素創(chuàng)建Outlets
  1. 打開(kāi)主storyboard;

  2. 點(diǎn)擊右上角的助手編輯器;


    assistant_editor_toggle_2x.png
  3. 在編輯選擇欄選中預(yù)覽ViewController.swift;


    3_switchtoviewcontroller_2x.png
  4. 在ViewController.swift代碼中找到類的定義行;

    class ViewController: UIViewController {

  5. 在定義行下面添加MARK注釋行;

    // MARK: Properties

帶有“// MARK:”開(kāi)頭的注釋是一種特殊的注釋,用于組織代碼和幫助導(dǎo)航到此處代碼

  1. 在storyboard界面上選中文本輸入框,按住Control鍵的同時(shí)鼠標(biāo)拖拽至ViewController.swift文件中“// MARK: Properties”代碼下面;
    ![Uploading 3_textfield_addoutlet_2x_321850.png . . .]


    3_textfield_dragoutlet_2x.png
  2. 在出現(xiàn)的對(duì)話框中Name欄中輸入nameTextField;


    3_textfield_addoutlet_2x.png
  3. 點(diǎn)擊“Connect”按鈕。

    @IBOutlet weak var nameTextField: UITextField!

Xcode將增加一個(gè)用于指向文本對(duì)話框的相應(yīng)代碼到ViewController.swift文件中,并配置storyboard建立上述連接。
IBOutlet屬性通知Xcode從界面編輯器(Interface Builder,前綴縮寫(xiě)IB)中連接到一個(gè)叫“nameTextField”的屬性,weak關(guān)鍵字表明該屬性有可能為nil,這個(gè)屬性類型為UITextField,其最后的“!”是隱式解包可選類型。

連接標(biāo)簽到ViewController.swift代碼中
  1. 選中storyboard中的標(biāo)簽對(duì)象,按住Control鍵的同時(shí)鼠標(biāo)拖拽至ViewController.swift代碼文件中聲明nameTextField屬性的代碼下面;


    3_label_dragoutlet_2x.png
  2. 在出現(xiàn)的對(duì)話框中Name欄中輸入mealNameLabel;


    3_label_addoutlet_2x.png
  3. 點(diǎn)擊“Connect”按鈕。
    同樣,Xcode將增加一個(gè)用于指向標(biāo)簽的相應(yīng)代碼到ViewController.swift文件中,并配置storyboard建立上述連接,同文本輸入框?qū)傩砸粯?,只是屬性名稱叫“mealNameLabel”,類型是UILabel。

    @IBOutlet weak var mealNameLabel: UILabel!

定義一個(gè)要執(zhí)行的動(dòng)作(Action)

iOS應(yīng)用程序是基于事件驅(qū)動(dòng)編程(event-driven programming),即應(yīng)用程序的執(zhí)行流向是由事件決定:系統(tǒng)事件和用戶動(dòng)作。用戶在界面上執(zhí)行動(dòng)作觸發(fā)應(yīng)用程序內(nèi)的事件,這些事件導(dǎo)致應(yīng)用程序的邏輯執(zhí)行和數(shù)據(jù)處理操作,應(yīng)用程序?qū)τ脩魟?dòng)作的響應(yīng)最終反映到界面中。
動(dòng)作(Action)是一個(gè)代碼片段,可以連接到出現(xiàn)在應(yīng)用程序上的某個(gè)事件。當(dāng)該事件發(fā)生時(shí),這些代碼得到執(zhí)行。定義一個(gè)動(dòng)作方法完成各種事務(wù),如操作一個(gè)數(shù)據(jù)塊或者更新界面等。使用動(dòng)作響應(yīng)用戶或系統(tǒng)的事件,來(lái)驅(qū)動(dòng)應(yīng)用程序的執(zhí)行流。創(chuàng)建一個(gè)動(dòng)作類似于創(chuàng)建一個(gè)outlet。

創(chuàng)建一個(gè)標(biāo)簽重置動(dòng)作(reset action)
  1. 在ViewController.swift類定義塊“}”添加MARK Action注釋代碼;

    // MARK: Actions

  2. 在storyboard中選中“設(shè)置缺省標(biāo)簽文字”按鈕,按住Control鍵的同時(shí)鼠標(biāo)拖拽至MARK Action注釋代碼下面;


    3_button_dragaction_2x.png
  3. 在出現(xiàn)的對(duì)話框中,Connection欄選擇Action;
  4. Name欄中輸入“setDefaultLabelText”;
  5. Type欄選擇UIButton;


    3_button_addaction_2x.png
  6. 點(diǎn)擊“Connection”按鈕。

Type欄的缺省為AnyObject,Swift語(yǔ)言中AnyObject表明一個(gè)可以屬于任何類的對(duì)象類型。Xcode將增加一段代碼到ViewController.swift文件中,并配置動(dòng)作方法。

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

上面代碼中,sender參數(shù)指向的對(duì)象導(dǎo)致觸發(fā)了動(dòng)作,本例是“設(shè)置缺省標(biāo)簽文字”按鈕。IBAction屬性表明本方法是一個(gè)從storyboard界面上連接的動(dòng)作。

代碼實(shí)現(xiàn)標(biāo)簽重置動(dòng)作
  1. 在ViewController.swift找到剛才添加的setDefaultLabelText動(dòng)作方法;
  2. 添加一行代碼。

    mealNameLabel.text = "Default Text"

上面完成的例子實(shí)現(xiàn)了iOS應(yīng)用程序設(shè)計(jì)中的”目標(biāo)-動(dòng)作”(target-action)模式,該模式用于當(dāng)一個(gè)指定事件發(fā)生時(shí)一個(gè)對(duì)象發(fā)送消息到另一個(gè)對(duì)象。本例中,這個(gè)事件是用戶點(diǎn)擊“設(shè)置缺省標(biāo)簽文字”按鈕,動(dòng)作是setDefaultLabelText,目標(biāo)是ViewController(動(dòng)作方法所在的類),發(fā)送著是“設(shè)置缺省標(biāo)簽文字”按鈕。”目標(biāo)-動(dòng)作”模式中,消息是在代碼中定義的一個(gè)動(dòng)作方法,目標(biāo)(target)是接收消息的對(duì)象-能夠執(zhí)行該動(dòng)作的對(duì)象,發(fā)送動(dòng)作消息的對(duì)象通常是一個(gè)控件(control),例如按鈕、滑桿(slider)、切換器(switch)等-觸發(fā)相應(yīng)的事件:點(diǎn)擊、拖拽或數(shù)值改變等。

處理用戶輸入

當(dāng)處理接收用戶在一個(gè)文本輸入框的輸入時(shí),需要用到文本輸入框代理(delegate)的一些幫助。當(dāng)文本輸入框的文本發(fā)生變化時(shí)或者發(fā)生重要事件如用戶開(kāi)始或終止編輯文本,會(huì)與其代理進(jìn)行通信,代理可以使用這些信息在合適的時(shí)機(jī)保存或清除數(shù)據(jù),關(guān)閉鍵盤(pán)屏幕等。任何對(duì)象作為另外一個(gè)對(duì)象的代理相當(dāng)于其遵從適應(yīng)的協(xié)議,一個(gè)定義文本輸入框代理的協(xié)議名為UITextFieldDelegate,本例因?yàn)閂iewController保持文本輸入框的一個(gè)引用,將其作為文本輸入框的代理,ViewController類采用UITextFieldDelegate協(xié)議。

采用UITextFieldDelegate協(xié)議
  1. 在ViewController.swift文件中找到class定義行;
  2. 使用”,”符號(hào)添加采用UITextFieldDelegate聲明。

    class ViewController: UIViewController, UITextFieldDelegate {

設(shè)置ViewController為文本輸入框nameTextField的代理
  1. 在ViewController.swift文件中找到viewDidLoad()方法;
  2. 在代碼行super.viewDidLoad()后面,添加下面代碼。

    nameTextField.delegate = self

self關(guān)鍵字引用ViewController類本,ViewController類就成為文本輸入框nameTextField的代理。

實(shí)現(xiàn)UITextFieldDelegate協(xié)議方法

UITextFieldDelegate協(xié)議包含選項(xiàng)方法,采用該協(xié)議的類可以不提供選項(xiàng)方法的實(shí)現(xiàn),本例為了完成一些行為,提供實(shí)現(xiàn)下面兩個(gè)方法的實(shí)現(xiàn)。

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

當(dāng)用戶點(diǎn)擊一個(gè)文本輸入框時(shí),該輸入框自動(dòng)成為一個(gè)首響應(yīng)者(first responder),第一個(gè)接收各種類型的應(yīng)用事件,包括按鍵事件、移動(dòng)事件和動(dòng)作消息等。 文本輸入框成為首響應(yīng)者的一個(gè)結(jié)果就是,iOS系統(tǒng)會(huì)顯示鍵盤(pán)小窗口,輸入框開(kāi)始一個(gè)編輯事務(wù)。當(dāng)用戶想要完成文本輸入框的編輯,該輸入框需要退出首響應(yīng)者狀態(tài)。因此上面兩個(gè)協(xié)議方法的實(shí)現(xiàn),會(huì)用于這個(gè)情況:用戶點(diǎn)擊一個(gè)按鈕來(lái)結(jié)束文本輸入框的編輯,這里用戶點(diǎn)擊“完成”(Done)或“返回”(Return),協(xié)議方法textFieldShouldReturn(_:)會(huì)被調(diào)用。

實(shí)現(xiàn)textFieldShouldReturn方法
  1. 在ViewController.swift文件中"http://MARK:Actions"上面添加MARK注釋代碼如下

    // MARK: UITextFieldDelegate

  2. 在下面輸入“func textfieldS”會(huì)出現(xiàn)自動(dòng)完成列表,顯示推薦的方法,選擇textFieldShouldReturn方法;

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

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

    textField.resignFirstResponder() return true

  4. 完整的代碼如下。

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

調(diào)用UITextField的resignFirstResponder方法退出首響應(yīng)者狀態(tài),返回true表明文本輸入框響應(yīng)用戶點(diǎn)擊Return按鍵后關(guān)閉鍵盤(pán)小窗口。

實(shí)現(xiàn)textFieldDidEndEditing方法

文本輸入框退出首響應(yīng)者狀態(tài)后,會(huì)調(diào)用textFieldDidEndEditing協(xié)議方法。

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

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

運(yùn)行模擬器

3_sim_defaulttext_2x.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 重要:這是針對(duì)于正在開(kāi)發(fā)中的API或技術(shù)的預(yù)備文檔(預(yù)發(fā)布版本)。蘋(píng)果提供這份文檔的目的是幫助你按照文中描述的方式...
    金_波閱讀 3,384評(píng)論 6 12
  • 讀萬(wàn)卷書(shū)不如行萬(wàn)里路,行萬(wàn)里路不如閱人無(wú)數(shù)
    田理閱讀 166評(píng)論 0 0
  • 170319@D75.感恩冥想 深深地感恩我擁有的一切!深深地感恩來(lái)到我身邊的家人們!祝全宇宙眾生夜夢(mèng)吉祥!
    佩詩(shī)閱讀 230評(píng)論 0 0
  • 一、定增法律意見(jiàn)書(shū)基本結(jié)構(gòu) 1、發(fā)行的主體資格 2、發(fā)行是否符合豁免向中國(guó)證監(jiān)會(huì)申請(qǐng)核準(zhǔn)股票發(fā)行的條件...
    哆啦A夢(mèng)萌萌噠閱讀 1,564評(píng)論 0 0
  • 今天領(lǐng)導(dǎo)單獨(dú)開(kāi)會(huì),可以說(shuō)是一次深度會(huì)議。。。也讓我開(kāi)始意識(shí)到自己已處于一個(gè)管理者的位置。 作為一個(gè)管...
    花言_花語(yǔ)閱讀 386評(píng)論 1 3

友情鏈接更多精彩內(nèi)容