連接UI到代碼


本章,你將連接FoodTracker應用程序的UI到代碼並定義一些可執行的動作。當你完成時,你的應用程序將是這個樣子:

 

學習目標
在課程結束時,你將能夠:
1.解釋一個storyboard中的場景和view controller之間的關系
2.在storyboard中UI元素和源代碼創建出口和連接動作
3.從文本字段處理用戶輸入並在UI中顯示結果
4.使用一個類遵循一個協議
5.理解委托設計模式
6.在設計應用程序體系結構時,按照目標 - 動作模式

連接UI到源代碼

在storyboard的元素鏈接到源代碼。重要的是要了解storyboard和你寫的代碼之間的關系。在storyboard中,一個場景代表的一個內容屏,通常一個視圖控制器。視圖控制器實現您的應用程序的行為。視圖控制器管理單個內容視圖和

它的子子視圖的層次。視圖控制器在應用程序的數據模型之間協調信息流,它封裝應用程序的數據,並且顯示數據,管理其內容視圖的生命周期,該設備被旋轉時,處理方向改變,定義應用程序的導航,並響應用戶輸入的行為。在所有的

iOS視圖控制器對象類型為UIViewController或其子類。通過創建和實現自定義視圖控制器子類來在代碼中定義您的視圖控制器的行為。然后,您可以創建你的storyboard,讓你在代碼中定義的行為,你在storyboard中定義的UI,並

把這些類和場景連接起來。Xcode中已經創建了這樣一個類,就是ViewController.swift,並將在storyboard中其連接到你工作的場景。在未來,當你添加更多的場景,你可以通過Identity inspector來鏈接。Identity inspector可以

在storyboard中編輯,你可以指定某個類和storyboard關聯起來

 

在運行時,你的storyboard將會創建一個ViewController的實例,你自定義的視圖控制器的子類。你在APP中看到的屏幕會在場景中顯示UI定義並在ViewController.swift中定義行為。雖然場景連接到了ViewController.swift,這不是需要做的唯一的連接。要和你的APP互動,你的視圖控制器源代碼需要能和View溝通。在storyboard中的view和視圖控制器源代碼文件之間,你通過定義額外的連接,如調用出口和動作

創建UI元素出口

出口(Outlet)提供一個方法來引用界面對象,前提是這些對象已經在你的storyboard中。為了創建一個outlet,在storyboard中從一個指定對象控制拖動到一個視圖控制器文件。這個操作會為你視圖控制器文件中的對象創建一個屬性,這個屬性能讓你在運行時的代碼中訪問和操作對象。你需要為文本框和標簽創建outlets來引用它們,步驟如下:

1.打開你的storyboard,Main.storyboard

2.點擊Assistant按鈕打開assistant editor,它在Xcode的頂部右邊

3.如果你想要更多空間,你可以折疊navigator,utility和outlin 區域,

4.在editor selector bar中頂部出現的assistant editor,從Preview改成Automatic > ViewController.swift

5.打開ViewController.swift類,添加一行注釋// MARK:

6.在storyboard中,選擇文本框

7.按下Control的同時拖動畫布中的文本框到代碼中,在注釋那一行停止拖動。如下圖所示:

 

8.在彈出的對話框中,的Name字段后,輸入nameTextField,然后就可以了,如下圖所示:

IBOutlet屬性告訴Xcode,你能從Interface Builder連接到nameTextField屬性(這就是為什么屬性前綴為IB)。weak關鍵字表示這個屬性可能沒有值(nil)。nameTextField表示聲明一個UITextField類的變量,末尾的感嘆號表示它是一個可選也可以是非可選的值,不需要每次訪問時,展開這個可選值,因為他假定總是有一個初始化的值,現在以相同的方式把標簽也連接到代碼。

@IBOutlet weak var mealNameLabel: UILabel!

定義要執行的動作(Action)

iOS應用程序都是基於事件驅動編程。系統事件和用戶動作:即,應用程序的流由事件決定。用戶在界面中執行動作來觸發的應用程序的事件。這些事件導致應用程序執行邏輯和操作它的數據。該應用程序的響應用戶的操作,然后反射回UI中。由於用戶,而不是開發者,用戶只會觸發一些動作,但到底哪些動作你想處理,你就可以寫對應的動作處理代碼。一般對於用戶的動作,我們需要友好的響應。一個動作(或動作方法)是一段代碼,它可以連接到發生在你應用程序中的事件。當該事件發生時,代碼被執行。你可以定義一個操作方法,從操縱一個數據來更新UI。你使用動作來驅動APP的流程,為了響應用戶或系統事件。你創建一個outlet,就是以同樣的方式創建一個動作:在你的storyboard中,Ctrl+拖動一個特定的對象打牌視圖控制器文件中。此操作會在你的視圖控制器的文件中創建方法,當用戶和對象交互時,動作的方法會被觸發。首先創建一個簡單的動作,當用戶點擊Set Default Label Text按鈕時,設置標簽的值為Default Text,接下來讓我們寫這個動作:

1.在最后一個大括號的前面寫下如下注釋

 

// MARK: Actions

 

這個注釋表示這段代碼會執行動作

2.在你的 storyboard中,選擇Set Default Label Text按鈕

3.按住Control鍵拖動畫布中的按鈕到右邊的編輯器中的代碼上,在你尷剛才注釋的代碼上停止拖動

 

4.早彈出的對話框中的Connection字段右邊選擇Action

5.Name字段右邊,鍵入setDefaultLabelText

6.Type字段右邊,選擇UIButton

你可能注意到Type的默認值是AnyObject,在Swift中AnyObject是一個類型,它用於描述一個可以輸入任意類的對象。指定動作的類型為UIButton意思是僅僅只有按鈕對象能連接到這個動作。雖然對你現在創建的動作沒有意義,但記住它是很有必要的,將來會用到,這時你的對話框應該如下圖所示:

 

7.點擊connect

Xcode會添加代碼到你的ViewController.swift中

@IBAction func setDefaultLabelText(sender: UIButton) {
}

sender參數指向觸發動作的對象,當前情況下是一個按鈕。IBAction屬性是表示這個方法是一個動作,你能從storyboard中連接到Interface Builder。剩余的setDefaultLabelText只是一個方法名。現在方法體中沒有代碼,實現重置標簽的代碼是很簡單的。下面讓我們來實現這個動作:

a.在ViewController.swift中找到你剛添加的setDefaultLabelText動作方法

b.在方法中實現如下代碼:

 

@IBAction func setDefaultLabelText(sender: UIButton) {
    mealNameLabel.text = "Default Text"
}

 

你可能猜到了,這個代碼是設置標簽文本的默認屬性。text是標簽對象中的屬性。注意,你不必指定默認文本的類型,因為Swift中可以正確類型推斷出它的類型。

檢查點:測試你的代碼,運行模擬器。當你單擊Set Default Label Text按鈕時,標簽會從Meal Name變成Default Text。

你剛才實現的行為是在iOSAPP設計target-action模式的一個例子。target-action設計是當特定事件發生時的其中一個對象將消息發送給另一個對象。在本例中,該事件是用戶輕敲Set Default Label Text按鈕,動作是setDefaultLabelText方法,目標的ViewController(定義動作方法的地方),而發送者是Set Default Label Text按鈕。該消息是在源代碼中定義的方法,目標是接收消息的對象,同時它也是一個能夠執行動作的對象。發送動作消息的對象通常是一個按鈕,滑塊,或開關,可以響應於用戶交互動作,如點擊,拖動。這種模式在iOS應用程序中非常普遍的,你會在后面看到更多。

處理用戶輸入

在這一點上,你必須有一個能重新設置標簽的默認值的一種方式,而現在你已經會添加行為,來設置文本框的值。為了簡單起見,你會依賴於用戶點擊文本框鍵盤上的Return 鍵的動作,指示標簽將會更新。

當您從文本框接受用戶輸入時,則需要從文本框委托一些幫助。委托是一個代表動作的對象,或另一個對象協調配合。在這種情況下的委托對象是文本框,委托對象將消息發送到委托。該消息告訴該委托有關該委托對象將要處理或剛處理的事件。委托可以響應由例如,更新對象外觀或狀態,可以是自身也可以是其他對象,或返回一個值,該值作用於一個即將到來的事件的處理方式。

當文字被編輯時,文本框的委托和文本框進行通信,並且知道在重大事件發生時,比如當用戶開始或停止編輯文本。委托可以在正確的時間使用這些信息來保存或清除數據,消除鍵盤,等等。

任何對象可以作為另一個對象的委托,因為它符合適當的協議。它定義了一個文本框的委托協議,被稱為UITextFieldDelegate。在這種情況下,由於ViewController保持了一個文本框的引用,所以你會讓ViewController成為文本框的委托。

首先,你需要有采用UITextFieldDelegate協議的ViewController。你可以通過將其列為類中的一行代碼來聲明采用一個協議。下面讓我們來看看UITextFieldDelegate協議是如何分配的

1.返回standard editor

2.在項目導航中,選擇ViewController.swift文件

3. ViewController.swift找到class這一行,如下所示:

class ViewController: UIViewController {

4.在UIViewController后,添加逗號和UITextFieldDelegate表示采用這個協議:

lass ViewController: UIViewController, UITextFieldDelegate {

通過采用該協議。這意味着你設置了文本框的委托,可以實現它的一些行為來處理文本框的用戶輸入。

接下來我們為nameTextField設置ViewController作為一個委托 

a.在ViewController.swift中,找到viewDidLoad()方法:

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
}

該模板此方法的實現,會自動生成注釋。你可以刪除注釋。

b.在super.viewDidLoad()下面添加一行代碼

// Handle the text field’s user input through delegate callbacks.
nameTextField.delegate = self

self表示ViewController自己。現在ViewController是一個為nameTextField服務的委托

UITextFieldDelegate協議包含了可選的方法,這表示你不必實現它們。但你可以獲得你想要的指定的行為,你可以還實現這兩個方法

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

為了理解當這些方法的調用時,他們需要做什么,重要的是知道文本框如何響應用戶事件,當用戶點擊文本框,會自動變成首要響應對象。在APP中首要響應對象是首先響應APP事件的對象,包括鍵盤事件,手勢事件,動作消息等。換句話說,許多由用戶生成的事件最初都會鏈接到首要響應

作為文本框變成首要響應事件的結果,iOS顯示鍵盤並開始為文本框編輯會話。通過鍵盤來鍵入類容到文本框中

當一個用戶想要完成文本框的輸入時,文本框需要放棄首要響應狀態。因為文本框不再是APP的當前對象,事件需要傳遞到更合適的對象中

這是實現UITextFieldDelegate進入方法的地方。當用戶點擊按鈕來結束編輯時,你需要指定文本框放棄它的首要響應狀態。你可以在textFieldShouldReturn()方法中這么做,它表示當用戶在軟鍵盤上點擊Return后的調用。

下面讓我們來實現UITextFieldDelegate協議的textFieldShouldReturn()方法

a.打開ViewController.swift

// MARK: UITextFieldDelegate

該注釋用於組織你的代碼,並幫助你(和其他讀你代碼的人)導航。
您已經添加了幾個這樣的注釋了。 Xcode中列出了所有這些注釋,作為源代碼文件的functions menu中的標題,如果你單擊該標題。你的代碼快速跳轉到一個地方。你會發現跳轉到了// MARK:注意冒號必須打

b.在注釋下方,添加方法

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

c.在方法中,添加如下代碼來放棄文本框的首要響應狀態。

// Hide the keyboard.
textField.resignFirstResponder()

當你輸入res的時候,Xcode強大的代碼完成功能,會讓你寫代碼更快,類似Eclipse等需要軟件都自帶這個強大省時的功能。

 

d.在方法中,添加如下代碼:

return true

因為這個方法返回一個布爾值,返回true表示文本框將響應用戶按下的返回鍵來讓軟鍵盤消失

你的textFieldShouldReturn方法看起來會是這樣:

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

第二個方法是textFieldDidEndEditing(),它在textFieldShouldReturn()之后調用。

textFieldDidEndEditing()方法給你一個機會讀取輸入到文本框中的信息,並用它做些什么。在本例中,我們會用文本框中的文本來改變你的標簽的值。

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

檢查點:測試你的代碼,運行模擬器。您可以選擇文本框,並輸入文本。當你點擊鍵盤上的Done 按鈕,鍵盤消失,標簽文字會變成文本框中的文本。當你單擊 Set Default Label Text按鈕時,標簽會顯示Default Text

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM