Xcode4.3開發第一個IOS應用實例

關於如何創建第一個 iOS 應用

本篇“第一個 iOS 應用”教程將向你介紹 iOS 應用開發中的“三個T”:

  • Tools(工具)如何利用 Xcode 創建和管理工程。
  • Technologies(技術)如何創建能夠響應用戶輸入的應用。
  • Techniques(技巧)如何充分利用 iOS 應用開發的基礎設計模式。

當你完成本教程的所有步驟之後,你的應用看起來會和下邊圖中的差不多:

appSimulator

從圖中可以看到,你創建的應用界面上有三個主要的元素:

  • 一個文本框(用戶把文字輸入到這裏)
  • 一個標籤(這裏可以用來顯示信息)
  • 一個按鈕(它能夠讓應用在標籤處顯示信息)

當你完成開發並運行應用時,點按文本框就會呼出系統提供的鍵盤。使用鍵盤輸入你的名字,關掉鍵盤(點按 Done 鍵),再點按 Hello 按鈕就會看到“Hello, 你的名字 !”出現在位於文本框與按鈕之間的標籤上。

要充分用好這份教程,如果已有一些基本的電腦編程概念並瞭解面向對象編程、Objective-C 語言是再好不過的了。如果你從未用過 Objective-C 也不要擔心,文中的代碼並不難懂。而且當你讀完全部《iOS 應用開發入門指南》路線圖之後,你會更好地理解代碼。

注意:你可以通過這份教程開始學習整個 iOS 平臺的應用開發,即便你只打算爲 iPad 進行開發。雖然教程中以 iPhone 界面舉例,但是所使用的工具和技術跟 iPad 應用開發是完全一樣的。


要跟隨本教程創建 iOS 應用,請先下載並安裝 Xcode 4.3 或更新版本。Xcode 是蘋果公司的集成式開發環境(IDE),可以同時用來開發 iOS 和 Mac OS X 應用程序。當你在 Mac 電腦上安裝 Xcode 之後,同時也會安裝 iOS SDK,其中包含了 iOS 平臺開發所需的接口等。

創建並測試新工程

開發新應用,從創建一個 Xcode 新工程開始。

如何創建新工程…

    1. 打開 Xcode(默認位置在 /應用程序 目錄下)。
      如果你從未使用 Xcode 創建或打開過工程,你將看到和圖中類似的 Xcode 歡迎界面:project_chooser如果你曾經創建或打開過 Xcode 工程,你可能就會看到工程窗口,而不是歡迎界面。
    2. 在 Xcode 歡迎界面中,點選“Create a new Xcode project”(或點選 File > New > Project)。
      Xcode 將開啓一個新窗口並顯示對話框,讓你選擇一個模板。Xcode 內置了幾套應用模板,可以方便開發常規 iOS 應用。例如,Tabbed 模板能夠創建一個和 iTunes 類似的應用,而 Master-Detail 模板能夠創建和 Mail 相似的應用。template_chooser
    3. 在對話框左側的 iOS 部分選擇 Application。
    4. 在對話框右側的主要區域選擇 Single View Application 然後點按 Next。
      接下來的對話框會讓你輸入應用的名稱,以及關於工程的一些額外信息。option_chooser_before
    5. 填寫 Product Name(產品名稱)、Company Identifier(公司標識)以及 Class Prefix(類前綴)。
      你可以按下面的內容填寫:
      • Product Name:HelloWorld
      • Company Identifier:如果你有公司,就填寫公司名稱。如果沒有,就填寫 edu.self
      • Class Prefix:HelloWorld

注意:Xcode 會使用你輸入的產品名稱爲工程以及應用程序命名。Xcode 會使用你提供的類前綴名稱來命名它爲你創建的類。例如,Xcode 會自動創建一個應用委託類並將其命名爲 HelloWorldAppDelegate。如果你填寫了其他的類前綴,那麼應用委託就會被命名爲 你的前綴名稱AppDelegate。(之後你會了解更多關於應用委託的內容。)

爲了講解的方便,本教程假定你的產品名爲 HelloWorld 並且你使用 HelloWorld 作爲類前綴。

  1. 在 Device Family 彈出菜單中,確認選中了 iPhone。
  2. 請確認 Use Storyboards 和 Use Automatic Reference Counting 選項是選中的,並且 Include Unit Tests 選項不被選中。
  3. 點按 Next.
    會出現另一個對話框,可以選擇在哪裏保存工程文件。
  4. 選擇一個保存位置(不要選中 Source Control 選項),然後點按 Create 完成創建。
    Xcode 便會打開一個新工程窗口(我們叫它工作區窗口),看上去應該和下圖類似:project_window

花幾分鐘時間來熟悉一下 Xcode 爲你打開的工作區窗口吧。在接下來的教程裏,你會經常用到圖中不同的區域和按鈕。

workspace_window_callouts

如果你的工作區窗口裏已經打開了實用工具區域(如上圖的黃色區域),你可以暫時將其關閉,稍後纔會用到它。在 View 按鈕中最右邊的就是實用工具區域的開關。當實用工具區域是顯示狀態時,該按鈕應該是按下去的:

utilites_button

如果需要,則可以點按 View 按鈕中的最右邊一個來關閉實用工具區域。

儘管迄今爲止你連一行代碼都沒有寫,其實你已經可以編譯此應用並在 iOS 模擬器中運行(已包含在 Xcode 中)。人如其名,iOS 模擬器能夠讓你直觀感受你的應用在 iOS 設備上運行起來是什麼樣子。

如何在 iOS 模擬器中運行你的應用…

  1. 首先確認一下 Xcode 工具條裏的 Scheme 菜單選中了 HelloWorld > iPhone 5.0 Simulator。
    如果該菜單顯示的不是這一項,那麼點開它並選擇 iPhone 5.0 Simulator。
  2. 點按 Xcode 工具條中的 Run 按鈕(或點選 Product > Run)。
    Xcode 會在工具條中央的活動查看器裏實時顯示構建過程。

當 Xcode 完成構建過程之後,模擬器就會自動運行(可能要等幾秒模擬器纔會出現在工作區窗口上方)。因爲你已經選擇過 iPhone(而不是 iPad),所以模擬器會顯示一個和 iPhone 一樣的界面。在虛擬的 iPhone 屏幕上,模擬器會自動運行你的應用,看上去應該是這樣的:

first_run

現在,你的應用裏什麼也沒有:它僅僅顯示一個白屏。要了解這個白屏來自哪裏的話,你需要學習代碼裏的對象,並且學習它們如何協同工作啓動這個應用。現在,請退出模擬器(點選 iOS Simulator > Quit iOS Simulator。請注意不要退出 Xcode)。

在你運行應用到時候,Xcode 可能會展開工作區窗口底部的 Debug(調試)區域。在本教程裏你不會用到這個區域,你可以將其關閉。

如何關閉調試區域…

  • 點按工具條裏 View 按鈕中的調試按鈕。
    View 按鈕中的調試按鈕是中間一枚,圖標是這樣的:debug_area_button

弄明白一個應用是如何運行起來的

由於你的工程是基於 Xcode 的一個模板建立的,在運行應用的時候,大部分基礎應用環境已經自動設置好了。例如,Xcode 會創建一個應用程序對象,它能夠建立一個運行循環(Run Loop,即一種事件處理循環。它能夠輸入資源並讓接收到的事件傳送到你的應用裏去)。這裏的大部分工作是由UIApplicationMain 函數完成的,這個函數是由 UIKit 框架提供的,在工程 main.m 源文件裏已經自動被調用。

注意:UIKit 框架提供了一個應用所需的從構建到管理用戶界面的所有類。UIKit 框架只是 Cocoa Touch 面向對象框架中的一種,它專爲 iOS 應用環境服務。

如何查看 main.m 文件的源代碼…

  1. 確保工程導航欄是打開的。
    工程導航欄顯示了工程裏的所有文件。如果工程導航欄沒有打開,點按導航欄選擇列最左邊的的按鈕:navigator_selector
  2. 在工程導航欄中打開 Supporting Files 文件夾,點按左側的三角形按鈕即可。
  3. 點選 main.m
    Xcode 會在此窗口的主要編輯器區域顯示文件裏的代碼,看上去應該和圖中類似:main_m_file

源文件 main.m 裏面的 main 函數會調用 UIApplicationMain 函數,並且是被包含在一個自動釋放池裏的:

@autoreleasepool {
   return UIApplicationMain(argc, argv, nil, NSStringFromClass([HelloWorldAppDelegate class]));

第一行的 @autoreleasepool 語句可以支持自動引用計數系統(ARC)。ARC 可以自動管理應用中的對象活動週期,確保在程序需要它們的時候一直存在,並在不需要的時候釋放這些對象。

調用 UIApplicationMain 函數時會創建一個 UIApplication 類的實例和一個應用委託的實例(在本教程中,應用委託就是 HelloWorldAppDelegate,這是 Single View 模板自帶的)。應用委託的主要任務就是提供一個窗口,從而讓你的應用能夠在裏面繪製內容。應用委託還能在應用界面顯示出來之前執行一些配置任務。(委託機制是一種設計模式,它規定:一個對象要代表另一個對象,或與另一個對象協同進行活動。)

在 iOS 應用中,窗口對象提供了一個可見容器,幫助把事件傳送到應用對象中去,並且幫助應用響應設備在方向上的改變。而窗口本身是不可見的。

調用 UIApplicationMain 函數同時還會掃描應用的 Info.plist 文件,這個文件是一個包含應用名稱、圖標等信息的屬性列表文件(即結構化的鍵/值對列表)。

如何查看屬性列表文件…

  • 在工程導航欄的 Supporting Files 文件夾裏,點選 HelloWorld-Info.plist
    Xcode 會在編輯器區域顯示 Info.plist文件的內容,看上去應該和圖中類似:info_plist在本教程中,你暫時無需瞭解 Supporting Files 文件夾裏的任何文件,所以可以收起它避免影響視線。收起文件夾也是點按 Supporting Files 文件夾左側的小三角按鈕。

因爲你剛纔選擇在此工程裏使用故事板,於是 Info.plist 文件裏同樣也會包含應用程序對象需要載入的故事板文件的名稱。故事板裏包含了定義此應用程序用戶界面的對象、過渡(Transition)以及連接(Connection)。

在 HelloWorld 應用中,故事板文件被命名爲 MainStoryboard.storyboard(注意,Info.plist 文件只會顯示文件名的前半部分)。當應用啓動時,MainStoryboard.storyboard 會被加載並且初始視圖控制器(Initial View Controller)會通過它創建實例。視圖控制器(View Controller)是一個對象,用來管理一片區域中的內容;初始視圖控制器就是應用啓動時被載入的第一個視圖控制器。

HelloWorld 應用只含有一個 View Controller(說白了就是 HelloWorldViewController)。現在,HelloWorldViewController 管理着一片區域的內容,它就是由一個視圖(view)提供的。視圖也是一種對象,它能夠在屏幕上一個矩形區域內進行繪製,並且處理用戶點、觸時產生的事件。一個視圖中可以包含其他視圖,被包含的視圖就叫做子視圖。當你向一個視圖內添加子視圖時,最外層的視圖叫做父視圖,而它的子視圖按理就被稱爲孩子視圖。父視圖和一系列孩子視圖(如果繼續包含下去,孩子視圖還會有自己的孩子視圖)共同構成視圖層級。一個視圖控制器管理一個層級的視圖。

注意:HelloWorld 應用對象被定義爲一種叫做模型-視圖-控制器(MVC)的設計模式,視圖及視圖控制器就是這三個角色中的兩個。第三個角色就是模型對象。在 MVC 裏,模型對象代表數據(例如日曆應用裏的一個代辦事項,或某畫圖應用裏的一個形狀),視圖對象知道如何顯示模型對象所提供的數據,而控制器對象則是模型和視圖中間的連接部分。在 HelloWorld 應用裏,模型對象是一個用來保存用戶輸入的姓名的字符串。目前你不用太深入地瞭解 MVC,但是如果能夠在設計過程中時刻想象你應用中的對象是如何扮演這三個角色的也很棒。

在接下來的步驟中,你需要在 HelloWorldViewController 管理的視圖中添加三個子視圖來形成視圖層級;這三個子視圖分別是一個文本框、一個標籤和一個按鈕。

在故事板中你可以看到視圖控制器和視圖的可視化表現形式。

如何查看故事板…

  • 在工程導航欄中點選 MainStoryboard.storyboard
    Xcode 會在編輯器區域打開故事板。(而故事板後邊的區域,也就是看上去像空白圖紙的區域,叫做畫布(Canvas))。

當你打開默認的故事板時,工作區窗口看起來應該和圖中類似:

storyboard_on_canvas

每個故事板都包含若干 Scene(場景)和 Segue(接續)。場景代表一個視圖控制器,接續代表兩個場景之間的過渡轉換。

由於 Single View 模板只提供一個視圖控制器,所以你應用的故事板裏就只有一個場景,沒有接續。畫布上場景左側的一個箭頭是初始場景指示器,表明它指着的場景是應用載入時第一個顯示的場景(典型情況下初始場景就相當於初始視圖控制器)。

你在畫布上看到的這個場景名稱是 Hello World View Controller 因爲它受 HelloWorldViewController 對象的管理。Hello World View Controller 是由 Xcode 大綱視圖裏顯示的若干個部件構成的。大綱視圖就是畫布和工程導航欄之間的那一欄。目前,視圖控制器包含一下幾個部件:

  • 一個 first responder 佔位符對象(由一個橙色的立方體標示)。 這裏的 first responder 是一個動態佔位符,代表應用運行過程中應該最先接收事件的對象。這些事件包括編輯焦點事件(例如點按文本框時呼出鍵盤),動作事件(例如搖晃設備),以及動作消息(例如用戶按下的按鈕發出的消息),等等這些。在本教程中你無需對 first responder 做任何修改。
  • 一個 HelloWorldViewController 對象(由一個嵌有矩形面板的橙色球體代表)。 當故事板載入一個場景時,它就會創建一個視圖控制器類的實例來管理這個場景。
  • 一個視圖,它被列在視圖控制器的下邊(要在大綱視圖裏顯示這個視圖,你需要點按 Hello World View Controller 旁邊的三角形按鈕來展開)。 這個視圖的白色背景便是你在模擬器中運行應用時看到的白屏。

注意:應用的窗口對象並不在故事板裏。

畫布中場景下面的部分叫做 Scene Dock(場景塢)。現在場景塢裏顯示了一些視圖控制器的名稱(也就是 Hello World View Controller)。在其他時候,場景塢可能包含一些代表 first responder 和視圖控制器對象的圖標。

本節回顧

在本章節裏,你使用 Xcode 創建了一個基於 Single View 模板的工程,並構建和運行了模板定義的默認應用。然後學習了工程中的一些基本要素,比如 main.m 源代碼文件,Info.plist 屬性列表文件,以及故事板文件,然後學習了關於應用如何啓動的原理。你還學到,你應用中的對象是如何分別代表模型-視圖-控制器(MVC)設計模式中這三個角色的。

在下一章節裏,你將學到關於視圖控制器及其視圖的更多內容。

正如你之前所學,一個視圖控制器負責管理一個場景,以及呈現一個區域裏的內容。這個區域中你看到的內容便是由視圖控制器中的視圖定義的。在這個章節中,你會更加細緻地觀察到由 HelloWorldViewController 管理的場景,並學會如何如何改變視圖的背景顏色。

使用檢視器來檢視視圖控制器

當一個應用啓動時,就會加載主故事板文件,並創建一個初始視圖控制器的實例。初始視圖控制器管理着用戶運行應用時看到的第一個場景。由於 Single View 模板只提供一個視圖控制器,它也就自然成爲初始視圖控制器。你可以利用 Xcode 檢視器(Inspector)來觀察視圖控制器的狀態等相關信息。

如何打開檢視器…

  1. 在工程導航欄點選 MainStoryboard.storyboard,畫布上就會出現它的場景。
  2. 在大綱視圖中,點選 Hello World View Controller(就位於 First Responder 下邊)。
    你的工作區窗口看上去應該和圖中類似:

    storyboard_vc_selected

    請注意場景和場景塢上同時顯示了一個藍色方框,而且場景塢中視圖控制器對象是被選中的狀態。

  3. 點按位於工具條上的 View 按鈕最右邊一個按鈕,展開右側的實用工具區域(或者點選 View > Utilities > Show Utilities)。
  4. 點選實用工具區域中的 Attributes(屬性)檢視器按鈕,打開屬性檢視器。
    檢視器按鈕是位於實用工具區域頂部檢視器選擇條中的第四個按鈕。

    attributes_inspector

    打開屬性檢視器後,你的工作區窗口看起來應該和圖中類似(可能你需要將窗口擴大來查看所有內容):

    vc_is_initial

    在屬性檢視器的 View Controller(視圖控制器)部分,你可以看到 Initial Scene(初始場景)選項是被選中的:

    initial_scene_option

    注意,如果你取消選擇這個選項,那麼畫布上的初始場景指示器就會消失。在本教程中,請確保 Initial Scene 選項一直是被選中狀態。

改變視圖的背景顏色

在之前的教程中,你曾學到應用在模擬器中運行時,你看到的白色背景就是由視圖提供的。要確保應用能夠正常運行,你可以將視圖的背景色替換成別的顏色,並查看應用在模擬器中運行時能否顯示新顏色。

在改變視圖背景顏色之前,請確保故事板在畫布上是打開的。(如果需要,請在工程導航欄中點選 MainStoryboard.storyboard 在畫布上打開故事板。)

如何設置視圖控制器中視圖的背景顏色…

  1. 在大綱視圖中,點按 Hello World View Controller 旁邊的三角箭頭(如果它是收起的狀態),然後點選 View(視圖)。
    Xcode 會高亮顯示畫布上的視圖區域。
  2. 在實用工具區域頂部的檢視器選擇條中點選 Attributes 按鈕,打開屬性檢視器。
  3. 在屬性檢視器中,點按 Background(背景)菜單那裏的白色矩形,打開 Colors(顏色)窗口。
    菜單中的矩形會顯示當前的背景顏色。Background 菜單看起來應該和圖中類似:

    background_color_button

    注意:如果不是點按白色矩形而是 Default 字符,則會彈出顏色選擇菜單,此時請之間點選 Other(其他)。

  4. 在 Colors 窗口中,點選除了白色的任意顏色。
    你的工作區窗口(包括 Colors 窗口)看上去應該和圖中類似:

    new_view_background

    需要注意的是,當你選擇一個視圖時 Xcode 會將其高亮顯示,此時畫布中的顏色因爲疊加可能會和 Colors 窗口中所選的顏色不太一致。

  5. 選好後關閉 Colors 窗口。

請確保 Xcode 工具條中 Scheme 菜單裏仍然顯示爲 HelloWorld > iPhone 5.0 Simulator。你看到的畫面應該和圖中類似:

running_with_new_color

提示:在運行應用之前,你無需手動保存工程。因爲當你按下 Run 按鈕(或點選 Product > Run)時,Xcode 就已經自動將你所做的修改全部保存了。

在繼續閱讀後面的教程之前,請把視圖的背景色改回白色。

如何把視圖的背景色改回來…

  1. 在屬性檢視器中,點按 Background 菜單中的箭頭打開菜單。
    請注意,Background 菜單中的矩形塊顏色已經變成了你剛纔在 Colors 窗口中選擇的顏色。如果你此時點按了矩形塊(而不是箭頭),那麼仍會打開 Colors 窗口。但是我們現在要使用的是視圖的原始背景色,所以點開 Background 菜單會更好尋找並直接應用原始顏色,而不是在 Colors 窗口裏調配。
  2. 在 Background 菜單中點選 Recently Used Colors(最近使用顏色)中的白色方塊。
  3. 點按 Run 按鈕,編譯並運行你的應用(當然,所做的修改會被自動保存)。

當你看到應用又能顯示出白色的背景時,就可以退出 iOS 模擬器了。

本節回顧

在本章節裏,你檢視了場景並改變(之後恢復)了視圖的背景顏色。

在下一章節中,你將要向視圖中添加一個文本框、一個標籤和一個按鈕,讓應用與用戶產生互動。


Xcode 提供了一個對象庫,方便將對象添加到故事板文件。其中,有些是用戶界面元素,屬於視圖類,比如按鈕、文本框等;其他的是更高等級的對象,比如視圖控制器、手勢識別器等。

Hello World View Controller 場景已經包含了一個視圖,現在你只需要再添加一個按鈕、一個標籤和一個文本框就可以了。然後你需要將這些部件和視圖控制器類連接起來,這樣它們才能夠按你需要的方式行事。

添加用戶界面元素

把對象庫裏的用戶界面(UI)元素拖放到畫布就可以將它們添加到視圖中去了。當 UI 元素被放到視圖中後,你可以按需要進行移動或縮放。

如何將 UI 元素添加到視圖,並恰當擺放…

  1. 在工程導航欄選中 MainStoryboard.storyboard,畫布上便會顯示出 Hello World View Controller 的場景。
  2. 打開對象庫。

    對象庫位於實用工具區域的底部。如果你沒有找到對象庫,可以點按庫選擇條中左起第三個按鈕:

    object_library

  3. 在對象庫的 Objects 菜單中選擇 Controls。

    Xcode 會在菜單下邊顯示一個控件(Controls)列表,列表裏包括各個控件的名稱和外觀以及關於其功能的簡要說明。

  4. 把文本框(text field)、圓角按鈕(round rect button)和標籤一次一個從列表中拖出來,並放置到視圖上去。

    dragging_text_field

  5. 拖動視圖中的文本框,讓它位於視圖的左上角。

    在你移動文本框(以及任意 UI 元素)時,會出現一些藍色的虛線,它們叫做對齊引導線,它們能幫你輕鬆在視圖中將 UI 元素對齊到邊界或中心位置。當文本框上邊和右邊同時出現對齊引導線時請停止拖動,如圖所示:

    moving_text_field

  6. 在視圖中,準備縮放文本框。

    通過拖拽 UI 元素上的縮放柄(Resize Handle),即位於元素邊緣上的白色小方塊,就可以縮放元素的大小。一般情況下,在畫布或者大綱視圖中點選某個元素時它的縮放柄就會出現。在這裏,文本框應該已經被選中,因爲你剛剛完成對齊拖放。如果你的文本框看起來和下邊的類似,那麼就可以進行縮放了。如果不一樣,請在畫布或者大綱視圖中點選它。

    resize_handles

  7. 向右拖動文本框右側的縮放柄,直到視圖右側出現對齊引導線。

    當你看到這樣的畫面時請停止拖拽:

    extending_text_field

  8. 保持文本框爲選中狀態,打開屬性檢視器。
  9. 在文本框屬性檢視器靠近頂部的位置,在 Placeholder(佔位符)框裏填寫 Your Name

    Placeholder 裏的文字可以幫助用戶理解文本框裏需要填寫哪些內容,在應用運行時提示文字以灰色呈現,並且在用戶點按文本框準備輸入時自動消失。

  10. 然後在文本框屬性檢視器裏,點按 Alignment(對齊)按鈕的中間一個,這樣可以讓文本框裏的文字居中對齊。

    當你輸入了佔位符文字以及修改了對齊選項之後,文本框屬性檢視器看起來應該和圖中類似:

    text_field_attributes

  11. 在視圖中,拖動標籤(Label)讓它位於文本框的正下方,其左邊和文本框的左邊對齊。
  12. 拖動標籤的右縮放柄,使其剛好和文本框等寬。

    可以看到,標籤的縮放柄比文本框的要多,因爲標籤可以橫向縮放也可以縱向縮放(但是文本框只支持橫向縮放)。我們不需要改變標籤的高度,因此請不要拖動標籤四個角上的縮放柄,而要拖動右側中間的那一個。

    resize_label

  13. 在標籤屬性檢視器中,同樣點按 Alignment 按鈕的中間一個,讓標籤裏顯示的文字居中對齊。
  14. 將按鈕拖動到視圖底部附近,並且放在視圖正中央。
  15. 在畫布上,連按按鈕並輸入文字 Hello
    當你在視圖中連按一個按鈕時(在輸入文本之前),你看到的應該和圖中類似:

    button_double_clicked

在添加了文本框、標籤和按鈕這些 UI 元素並按上述方法修改佈局以後,你的工程看起來應該和圖中類似:

after_layout

文本框還有另外幾個選項,通過修改這些選項可以讓文本框的行爲更加符合用戶的預期。首先,用戶會根據提示輸入自己的名字,你可以確保 iOS 建議讓每一個單詞首字母都大寫;其次,你要確保和文本框關聯的鍵盤設置適合於輸入姓名(而不是數字什麼的),而且要讓鍵盤中顯示一個 Done(完成)按鈕。

這些修改都基於一個原則:既然你清楚文本框裏將要輸入什麼內容,那麼就應該將其外觀及動作設置到最適合用戶完成相應任務的狀態。所有調整和配置都可以在屬性(Attributes)檢視器中完成。

如何配置文本框…

  1. 在視圖中,選中文本框。
  2. 在文本框屬性檢視器中,進行以下幾項修改:
    • 在 Capitalization(大寫)菜單裏選擇 Words(單詞)。
    • 確保 Keyboard(鍵盤)菜單選擇的是 Default(默認)。
    • 在 Return Key(回車鍵)菜單裏選擇 Done(完成)。
  3. 當你完成這些配置後,文本框屬性檢視器看起來應該是這個樣子:

    text_field_entry_attributes

在 iOS 模擬器中運行你的應用,確保你添加的所有 UI 元素看起來都是你所希望的樣子。你在點按 Hello 按鈕時,它應該會高亮一下,如果你點按文本框裏面的部分,鍵盤就應該顯示出來。目前按鈕還沒有任何功能,標籤也只會顯示“Label”,並且鍵盤一旦被調出就無法收回去了。要添加你需要的功能,就得把 UI 元素和視圖控制器進行正確連接。接下來,我們來看如何進行連接。

注意:由於你正在 iOS 模擬器中運行此應用,而不是真實設備中,你激活控件的方式是點按而不是真實的輕敲。

爲按鈕創建動作

當用戶激活某個 UI 元素時,該元素會發送一個消息給能夠做出對應的動作的對象(例如“將此聯繫人添加到用戶的聯繫人列表中”)。這種交互行爲是“目標-動作機制(Target-action mechanism)”中的一部分,這是另一個 Cocoa Touch 的設計模式。

在這篇教程裏,用戶輕敲 Hello 按鈕時,你要讓按鈕給視圖控制器(即目標)發送一個“更改歡迎辭”的消息(即動作)。這個消息將修改一個由視圖控制器管理的字符串(也就是模型對象)。然後,視圖控制器去更新標籤裏顯示的文字,反映出模型對象中這個值的改變。

在 Xcode 中,給某個 UI 元素添加動作並設定相應的動作方法的途徑是:按住 Control 鍵並從畫布上的該元素拖動到合適的源文件上(一般而言就是視圖控制器的源文件)。故事板會把通過這種方式建立的連接進行存檔。之後,當應用運行載入故事板時,這些連接就會被還原出來。

如何給一個按鈕添加動作…

  1. 在工程導航欄裏選擇 MainStoryboard.storyboard,畫布中會顯示其場景。
  2. 在 Xcode 工具條裏,點按 Utilities(實用工具)按鈕關閉實用工具區域,然後點按輔助編輯器按鈕(Assistant Editor)調出輔助編輯器面板。

    輔助編輯器按鈕位於 Editor(編輯器)按鈕中間,圖標是這樣的:

    assistant_editor_button

  3. 確保輔助編輯器裏顯示的是視圖控制器的頭文件(即 HelloWorldViewController.h)。
  4. 在畫布中,按住 Control 並從 Hello 按鈕拖動到 HelloWorldViewController.h 的方法聲明部分(即 @interface 語句到 @end 語句之間的部分)。
    按住 Control 並拖動的時候,你看到的應該和圖中類似:

    dragging_for_action

    拖動到目標位置並鬆開 Control 鍵後,Xcode 將彈出一個配置框,在裏面可以配置你剛剛完成的動作連接:

    connection_popover

    注意:如果按住 Control 鍵拖動時在 HelloWorldViewController.h 的方法聲明區域以外的地方鬆開,你將會看到其他樣子的彈出框甚至什麼也不會出現。如果不小心這樣,可以點按畫布中的視圖來取消該彈出框(如果需要的話),然後再次按住 Control 鍵拖動。

  5. 在彈出框中,這樣配置按鈕的動作連接:
    • 在 Connection(連接)菜單中,點選 Action(動作)。
    • 在 Name(名稱)文本框裏輸入 changeGreeting:(可不要漏掉那個冒號呀)。 接下來的步驟中,你需要實現 changeGreeting: 方法,這樣才能真正讓它將用戶輸入的文字“放”到標籤上顯示出來。
    • 確保 Type(類型)文本框裏是 id
      id 型數據可以標示任何一種 Cocoa 對象。我們在這裏選用 id 是因爲無需關心發送消息的對象究竟是什麼。
    • 確保 Event(事件)菜單裏選中的是 Touch Up Inside。 之所以選用 Touch Up Inside 事件是因爲我們要在用戶的手指在按鈕範圍內擡起時發送消息。
    • 確保 Arguments(參數)菜單中選中的是 Sender。
  6. 當你配置完動作連接之時,彈出框裏的內容看上去應該和圖中類似:

    action_popover

  7. 點按彈出框右下角的 Connect(連接)。

    Xcode 會爲新的 changeGreeting: 方法添加一個存根實現,並且在這個方法的左側顯示一個內部有填充的圓形來標示已經進行過連接:

    action_connection_made

當你按住 Control 鍵並從按鈕元素拖動到 HelloWorldViewController.h 文件並配置對應的動作時,其實你完成了兩件事:

  • 你向視圖控制器類添加了適當的代碼。明確地說,你向 HelloWorldViewController.h 添加了如下動作方法聲明:

    - (IBAction)changeGreeting:(id)sender;

    並讓 Xcode 向 HelloWorldViewController.m 文件添加了如下存根實現代碼

    - (IBAction)changeGreeting:(id)sender {
    }

    注意:IBAction 是一個特殊的關鍵詞,用來告訴 Xcode 把一個方法當成目標-動作連接來看待。IBAction 被定義爲 void

    而動作方法中的 sender 參數指向的是動作消息的發送者(在這篇教程裏,發送者就是按鈕)。

  • 你已經在按鈕和視圖控制器之間建立好連接了。

接下來,需要在視圖控制器和剩下的兩個 UI 元素之間建立連接,即標籤和文本框。

爲文本框和標籤創建插座變量(Outlet)

插座變量(Outlet)描述的是兩個對象之間的連接。當你需要讓一個對象(例如視圖控制器)與它所包含的一個對象(例如文本框)進行溝通時,你就會把被包含的那個對象稱爲插座變量。當應用運行起來時,你在 Xcode 裏創建的插座變量就被還原出來了,這樣在運行時這些對象就可以相互交流了。

在本篇教程中,我們需要讓視圖控制器獲取用戶在文本框裏輸入的文字並將其顯示到標籤上。爲了確保視圖控制器能夠和這些對象進行溝通,你要在它們之間創建插座變量連接。

要爲文本框和標籤添加插座變量,步驟和添加按鈕動作時的很相似。在開始操作之前,確保畫布上仍然可以看到主故事板文件,並且  HelloWorldViewController.h 在輔助編輯器中是打開的。

如何爲文本框添加插座變量…

  1. 按住 Control 鍵並從視圖中的文本框拖動到頭文件的方法聲明區域。
    當你進行 Control 拖動時,看起來應該和圖中差不多:

    dragging_for_outlet

    只要按住 Control 拖動到了方法聲明的區域裏,並在區域裏的任何地方鬆開便可。在本篇教程中,文本框和標籤的插座變量聲明顯示在 Hello 按鈕的方法聲明上邊。

  2. 完成 Control 拖動並鬆開時,會出現一個彈出框,請這樣配置文本框的連接:
    • 確保 Connection(連接)菜單裏選中的是 Outlet。
    • 在 Name(名稱)文本框裏輸入 textField
      你怎麼稱呼這個插座變量都行,但插座變量和它所代表的物體在名稱上有關聯的話,你的代碼會更易讀。
    • 確保 Type(類型)文本框裏是 UITextField
      將 Type 文本框設置爲 UITextField 就確保 Xcode 只會把這個插座變臉和文本框相連接。
    • 確保 Storage(存儲)菜單中選中的是 Weak(弱),這也是默認選項。
  3. 當你完成配置之後,此時的彈出框看上去應該是這樣的:

    configure_text_field_outlet

  4. 點按彈出框右下角的 Connect(連接)。

爲文本框添加插座變量時,你實際上完成了兩件事:

  • 你向視圖控制器添加了適當的代碼。明確地說,就是你向 HelloWorldViewController.h 中添加了下列聲明:

    @property (weak, nonatomic) IBOutlet UITextField *textField;

    注意:IBOutlet 是一個特殊關鍵詞,用來告訴 Xcode 把該對象當作插座對象來對待。它實際上未被定義爲任何東西,所以在編譯時是沒有影響的。

    同樣,你還讓 HelloWorldViewController.m 文件的 viewDidUnload 方法裏新增了下列語句:

    self setTextField:nil;

    viewDidUnload 方法是由你選用的 Xcode 模板提供的,並且 UIKit 框架已經幫你實現它了。當某個視圖控制器需要卸載它所包含的某個視圖時,就會調用 viewDidUnload 方法,因此這個方法正好可以用來將視圖的插座變量設爲 nil

  • 你已經建立好了從視圖控制器到文本框的連接。

    在視圖控制器和文本框之間建立連接後,用戶輸入的文字就會被髮送給視圖控制器。在 changeGreeting: 方法聲明的部分,Xcode 會在文本框聲明語句的左側顯示一個含有填充的圓形表示已經連接。

現在給標籤也添加一個插座變量並配置連接。在視圖控制器和標籤之間建立連接後,視圖控制器就可以用包含用戶輸入文字的一個字符串來更新標籤顯示的內容。這一步的步驟和剛纔給文本框添加插座變量時是相同的,只不過在配置連接時稍有區別。(確保輔助編輯器中的內容是 HelloWorldViewController.h。)

如何給標籤添加插座變量…

  1. 按住 Control 鍵並從視圖上的標籤拖動到輔助編輯器裏 HelloWorldViewController.h 的方法聲明區域。
  2. 鬆開後會出現彈出框,請按如下方式配置標籤的連接:
    • 確保 Connection(連接)菜單裏顯示的是 Outlet(插座變量)。
    • 在 Name(名稱)文本框中填入 label
    • 確保 Type(類型)框裏顯示的是 UILabel
    • 確保 Storage(存儲)菜單裏顯示的是 Weak(弱)。
  3. 點按彈出框右下角的 Connect(連接)。

跟着教程走到這一步,你已經創建了三個到視圖控制器的連接:

  • 一個按鈕的動作連接
  • 一個文本框的插座變量連接
  • 一個標籤的插座變量連接

在 Connections(連接)檢視器中可以檢驗這些連接。

如何打開視圖控制器的連接檢視器…

  1. 點按 Standard(標準)編輯器按鈕來關閉輔助編輯器,切換到標準編輯視圖。
    標準編輯器按鈕是 Editor 按鈕中最左邊一個,看上去是這個樣子:

    standard_editor_button

  2. 點按 View 按鈕中的 Utilities(實用工具)按鈕,打開實用工具區域。
  3. 在大綱視圖中點選 Hello World View Controller。
  4. 在實用工具區域打開連接檢視器。
    連接檢視器按鈕在檢視器選擇條的最右邊,看上去是這個樣子:

    connections_inspector_button

在連接檢視器中,Xcode 會顯示選中對象的所有連接情況(在這裏是視圖控制器的所有連接)。在工作區窗口,你應該能夠看到圖中的畫面:

verify_connections

注意,除了你創建的三個連接之外,視圖控制器和它的視圖之間也有連接。Xcode 默認會在視圖控制器和它的視圖之間自動做好連接,你可以不必理會。

爲文本框的委託建立連接

你的應用裏還缺少一個連接:你需要規定某個對象爲文本框的委託(Delegate),並在文本框和文本框委託之間建立連接。在本教程中,你將使用視圖控制器作爲文本框委託。

爲什麼要給文本框規定委託對象呢?因爲當用戶輕敲鍵盤中的 Done 按鈕時,文本框要給它的委託發送消息(回憶一下,委託是一種對象,它代表另一個對象執行動作)。在之後的步驟裏,你要利用跟這個消息相關聯的方法來收起鍵盤。

確保故事板文件顯示在畫布上。如果沒有,請在工程導航欄中點選 MainStoryboard.storyboard

如何爲文本框設定委託…

  1. 在視圖中,按住 Control 鍵並從文本框拖動到場景塢裏的黃色球體上(黃色球體代表視圖控制器對象)。
    當你鬆開時,應該能看到圖中的畫面:

    text_field_delegate

  2. 當半透明面板出現時,選擇 Outlets(插座變量)部分的 delegate

測試應用

點按 Run 來測試你的應用。

現在你應該可以看到,在點按 Hello 按鈕時它會高亮,點按文本框內部時會出現鍵盤並且能夠輸入文字。然而,我們仍然無法收起鍵盤。在下一章節裏,我們將實現這個功能,也就是實現適當的委託方法。現在請退出 iOS 模擬器。

本節回顧

當你在畫布中的視圖控制器和輔助編輯器中的 HelloWorldViewController.h 文件之間建立了合適的連接以後,你同時也更新了實現文件(即 HelloWorldViewController.m 文件)來支持相應的插座變量和動作。如果想要檢視實現文件中發生的變化,在工程導航欄中打開它即可。

在創建連接時,你也可以不使用 Xcode 的自動添加代碼功能(即按住 Control 鍵從畫布拖動到源代碼中)。相反,你完全可以把屬性聲明和方法聲明手動輸入到頭文件中,然後建立文本框到它的委託的連接。當然了,儘量使用 Xcode 的自動功能可以幫助你減少輸入錯誤(同時也能減少一點手動輸入工作)。

要實現視圖控制器,需要做好幾件事:爲用戶的姓名添加一個屬性、實現 changeGreeting: 方法、確保用戶輕敲 Done 按鈕時鍵盤能夠收起來。

 爲用戶的姓名添加一個屬性

用戶的姓名由一個字符串保存着,首先要爲該字符串聲明一個屬性,這樣你的代碼才能引用它。請將此聲明添加到視圖控制器的頭文件中(即 HelloWorldViewController.h)。

屬性聲明是一個指令,它會告訴編譯器如何爲變量生成存取方法(Access method),例如這裏的用來保存用戶姓名的變量。(完成添加屬性聲明之後,你會學到什麼是存取方法。)

在本教程中,你無需對故事板文件進行任何改動。接下來的代碼比較多,爲了給自己騰出必要的工作空間,可以點按 View 按鈕中的實用工具按鈕關閉實用工具區域(或者點選 View > Utilities > Hide Utilities)。

如何爲用戶的姓名添加屬性聲明…

  1. 在工程導航欄中點選 HelloWorldViewController.h
  2. 在 @end 語句之前,爲字符串添加一個 @property 語句。
    屬性聲明語句應該是這樣的:

    @property (copy, nonatomic) NSString *userName;

    你可以將這行代碼拷貝並粘貼到編輯器面板中,也可以手動輸入。如果你要手動輸入,就能注意到 Xcode 會針對你的輸入提供補全建議。比方說你開始輸入 @pro… 時 Xcode 就會猜測你可能想要輸入 @property,於是就會在這行語句下面顯示一個建議面板,如圖:

    inline_suggestion

    如果該建議是正確的(如上圖的例子),則可以按回車鍵接受之。

    在你繼續輸入代碼時,Xcode 也許會提供一系列建議讓你挑選。比如在你輸入 NSSt… 的時候,Xcode 可能會顯示類似圖中的補全建議:

    completion_list

    當 Xcode 顯示補全列表時,按回車鍵就可以接受當前高亮顯示的那一個語句了。如果高亮顯示的並非你所需的語句(比如上圖中的例子),可以按方向鍵在列表中選擇合適的項目。

要完成 userName 屬性的實現,你還需要讓編譯器合成相應的存取方法。存取方法是用來讀取或設置對象屬性的值的方法(有時,存取方法也被稱作“getter”和“setter”)。

Xcode 會產生一個警告,提示你必須合成相應的存取方法。在活動查看器裏會顯示一個黃色的警告符號:

warning

此時,你已經知道 Xcode 的警告是什麼,所以不必查看警告的詳細信息。若需要查看警告信息的具體內容,你可以點按活動查看器中的黃色警告圖標,並在問題導航欄中查看細節:

issue_navigator

在本篇教程裏,你不會再用到問題導航欄。請點按導航選擇條最左邊的按鈕返回工程導航欄。

接下來,你需要向視圖控制器的實現文件(即 HelloWorldViewController.m)中輸入代碼,讓編譯器生成存取方法。

如何爲用戶的姓名屬性生成存取方法…

  1. 在工程導航欄中點選 HelloWorldViewController.m
  2. 在 @implementation HelloWorldViewController 這行的下面,輸入如下代碼:

    @synthesize userName = _userName;

    輸入這段代碼之後,Xcode 就不會再警告你缺少存取方法了,於是警告圖標也就從活動查看器中消失了。

當編譯器遇到 @synthesize 指令時,它實際上會自動爲你生成下面兩個存取方法:

- (NSString *)userName
- (void)setUserName:(NSString *)newUserName

由於在 @synthesize 語句裏的 userName 添加了一個下劃線,編譯器便知道 _userName 是 userName 屬性的一個實例變量名稱。而你之前沒有爲名爲 _userName 的實例變量進行聲明,這段代碼就會向編譯器請求爲它也生成存取方法。

注意:編譯器生成存取方法只會在已編譯的代碼中進行,而不會改動你的源代碼文件。

 實現 changeGreeting: 方法

在上一個章節“對視圖進行調整”裏,你配置了 Hello 按鈕的動作,在用戶輕敲按鈕時它便給視圖控制器發送一個 changeGreeting: 消息。爲了響應此消息,你會讓視圖控制器在標籤上顯示一段文字,包含用戶剛剛輸入的內容。具體而言,changeGreeting: 方法應該:

  1. 從文本框取回字符串,並將視圖控制器的 userName 屬性值設置爲這個字符串。
  2. 根據 userName 屬性創建一個新字符串,並將其顯示在標籤上。

如何實現 changeGreeting: 方法…

  1. 在工程導航欄中點選 HelloWorldViewController.m

    你可能要移動到文件末尾纔會看到 Xcode 爲你添加的 changeGreeting: 存根實現。

  2. 將 changeGreeting: 方法的存根實現補全,請輸入如下代碼:

    - (IBAction)changeGreeting:(id)sender {

        self.userName = self.textField.text;

        NSString *nameString = self.userName;
        if ([nameString length] == 0) {
            nameString = @”World”;
        }
        NSString *greeting = [[NSString alloc] initWithFormat:@”Hello, %@!”, nameString];
        self.label.text = greeting;
    }

在 changeGreeting: 方法中有好幾個有趣的地方:

  • self.userName = self.textField.text; 從文本框取回文字,並將視圖控制器的 userName 屬性值設置爲該文字。
    在本篇教程中,你可能不會在其他地方用到存有用戶姓名的這個字符串,但仍然需要明白它的作用:它是非常簡單的一個模型對象,由視圖控制器管理。通常情況下控制器會在自己的模型對象中保存關於應用數據的信息,該數據信息不應該被保存在用戶界面元素中,例如 HelloWorld 的文本框。
  • NSString *nameString = self.userName; 會創建一個新的變量(類型爲 NSString)並將它的值設爲視圖控制器 userName 屬性的值。
  • @”World” 是一個字符串常量,由一個 NSString 類的實例來表示。如果用戶運行應用時沒有輸入任何文字(即滿足 [nameString length] == 0 這個條件),nameString 就會包含字符串“World”。
  • initWithFormat: 方法是由 Foundation 框架提供給你的。它根據你提供的格式化字符串的格式創建一個新的字符串(這一點和 C 語言中的 printf函數很相近,你也許對它比較熟悉)。
    在格式化字符串中,%@ 代表字符串對象的佔位符。雙引號中的其他字符則會原封不動地顯示在屏幕上。

將視圖控制器配置爲文本框的委託

如果你構建並運行應用,你應該會發現點按按鈕時標籤顯示“Hello World!”字樣。可是當你點選了文本框並輸入一些文字時,則會發現仍然無法通過點按 Done 來收起鍵盤。

在一個 iOS 應用中,一旦能夠接受文字輸入的 UI 元素成爲 first responder 就會自動調出鍵盤。反過來,該元素失去 first responder 狀態時鍵盤就會自動收起。(請回憶一下 first responder 是什麼:它是在若干事件中第一個接收通知的對象,例如輕敲文本框就會呼出鍵盤。)雖然不能直接從你的應用給鍵盤發送消息,但你可以通過改變文字輸入 UI 元素的 first responder 狀態來呼出和收起鍵盤。

而 UITextFieldDelegate 協議是由 UIKit 框架定義的,其中包含了一個 textFieldShouldReturn: 方法,它在用戶輕敲回車鍵(無論回車鍵的標題被改成什麼)是被文本框調用。因爲我們已經將視圖控制器設爲了文本框的委託(在上一章節“對視圖進行調整”),你可以通過實現這個方法來強制文本框失去 first responder 狀態,給它發送一個 resignFirstResponder 消息即可,通過這個方式就能收起鍵盤。

注意:協議從根本上講就是一系列方法的集合。如果某個類遵守(或採用了)某個協議,它也就承諾一定會實現協議中規定的所有方法。(協議也可以包含可選方法。)委託協議指定了對象可能發送給委託的所有消息。

如何配置文本框的委託 HelloWorldViewController …

  1. 在工程導航欄中點選 HelloWorldViewController.m
  2. 實現 textFieldShouldReturn: 方法。
    這個方法會讓文本框失去 first responder 狀態。實現的代碼如下:

    - (BOOL)textFieldShouldReturn:(UITextField *)theTextField {
        if (theTextField == self.textField) {
            [theTextField resignFirstResponder];
        }
        return YES;
    }

    在本應用中,並非一定要包含 theTextField == self.textField 這個檢查語句,因爲只有一個文本框。不過這個模式非常值得反覆使用,因爲在某些情況下某個對象可能會成爲類型相同的多個對象的委託,你就需要嚴格區分它們了。

  3. 在工程導航欄中點選 HelloWorldViewController.h
  4. 在 @interface 行的結尾添加 <UITextFieldDelegate>
    你的接口聲明應該是這樣的:

    @interface HelloWorldViewController : UIViewController <UITextFieldDelegate>

    這段聲明指定了你的 HelloWorldViewController 類要採用 UITextFieldDelegate 協議。

最終測試應用

構建並運行應用吧。這一次,所有功能應該都已達到我們的預期效果。在 iOS 模擬器中,輸入完你的姓名後點按 Done 按鈕來收起鍵盤,然後點按 Hello 按鈕在標籤裏顯示“Hello, 你的姓名!”。

如果應用還是沒能按照預期效果工作,你就需要排查一下問題了。下一章節“故障排除以及代碼檢查”裏將介紹可能出錯的幾個地方。

本節回顧

那麼,你終於把視圖控制器的實現也做好了,你做出了你的第一個 iOS 應用,祝賀你!


如果你的應用仍然無法正常工作,請根據本章節來嘗試進行故障排查。如果仍然無法找到錯誤,請按照本章節最後的代碼清單和你的代碼進行逐一比對。

代碼和編譯器警告

你的代碼應該能夠無警告並通過編譯。如果發現有警告出現,建議你將它們當成錯誤來看待。因爲 Objective-C 是個非常靈活的語言,有時候編譯器頂多把一些地方判定成警告而不是錯誤。

檢查故事板文件

作爲一名開發者,如果發現有東西運行不正常,出於自然的直覺你大概會去檢查源代碼中的漏洞。但是在 Cocoa Touch 開發中,需要注意另一件事:你的應用中許多配置可能被“編碼”到了故事板文件中。打個比方,如果你的連接不正確,應用也不會如預期那樣正常工作。

  • 如果點按按鈕後文字沒有更新,則可能是按鈕的動作沒有和視圖控制器正確連接,或者是視圖控制器的插座變量沒有和文本框或者標籤正確連接。
  • 如果你點按 Done 按鈕後鍵盤並未收回,則有可能是文本框的委託或者視圖控制器的 textField 插座變量沒有跟文本框正確連接。請務必檢查故事板中文本框的連接情況:按住 Control 鍵並點按文本框,調出半透明的連接面板。你應該看到 delegate 插座變量以及 textField 引用旁邊是帶有填充的圓形。

    如果你確實連接了委託,那麼可能存在某些更加微妙的問題(參看下邊的“委託方法名稱”)。

委託方法名稱

委託中常見的一個錯誤就是拼錯委託方法的名稱。就算正確設定了委託對象,但是如果委託沒有使用方法實現中的正確名稱,則正確的方法就永遠也不會被調用。最好的建議是從開發者文檔中拷貝和粘貼委託方法的聲明,比如 textFieldShouldReturn:

代碼清單

在這個部分,HelloWorldViewController 類的接口和實現文件都被完全羅列出來。需要注意的是本代碼清單不包含由 Xcode 模板提供的其他方法實現以及代碼註釋。

接口文件:HelloWorldViewController.h

#import <UIKit/UIKit.h>

@interface HelloWorldViewController : UIViewController <UITextFieldDelegate>

@property (weak, nonatomic) IBOutlet UITextField *textField;
@property (weak, nonatomic) IBOutlet UILabel *label;
@property (nonatomic, copy) NSString *userName;

- (IBAction)changeGreeting:(id)sender;

@end

實現文件:HelloWorldViewController.m

#import “HelloWorldViewController.h”

@implementation HelloWorldViewController

@synthesize textField=_textField;
@synthesize label=_label;
@synthesize userName=_userName;

 
- (BOOL)textFieldShouldReturn:(UITextField *)theTextField {
    if (theTextField == self.textField) {
        [theTextField resignFirstResponder];
    }
    return YES;
}

- (IBAction)changeGreeting:(id)sender {
    self.userName = self.textField.text;

    NSString *nameString = self.userName;
    if ([nameString length] == 0) {
        nameString = @”World”;
    }
    NSString *greeting = [[NSString alloc] initWithFormat:@”Hello, %@!”, nameString];
    self.label.text = greeting;
}
@end


本文來源:http://www.guomii.com/posts/20266
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章