《MonoTouch开发实践指南》一1.2 创建MonoTouch应用程序
1.2 創建MonoTouch應用程序
在本節中,將編寫一個帶有標簽和按鈕的簡單應用程序,并通過單擊按鈕來改變標簽的文本顯示。完成后的應用程序將如圖1-10所示。
1.2.1 創建用戶界面
首先要做的是創建用戶界面。返回剛才在MonoDevelop創建的包含一個空白窗口的應用程序,如果IB還沒打開,雙擊MainWindow.xib文件打開IB。前面提及過,IB是蘋果的用戶界面設計工具,可以用它來創建應用程序的界面。如果曾經進行過Windows或ASP.NET開發,就會覺得它的作用有點類似于Visual Studio中的設計工具,但是功能不同。IB管理的是xib文件,它是一個XML格式的文件,在文件里封裝了所有定義應用程序用戶界面的對象。當生成應用程序時,xib文件會轉換為以.nib為擴展名的二進制格式文件(這就是常說的“nib文件”)。基本上,xib文件就是UI層的序列化對象圖。現在,可根據以下步驟創建一個用戶界面:
1)在IB中,如圖1-11所示那樣在Library窗口中選擇Objects(對象)標簽頁。
2)在Library窗口內滾動中間區域的滾動條,直到看到類型為UILabel的標簽控件(Label)。然后將它拖動到窗口的設計界面上,并放置在靠窗口頂部的位置。
3)現在,添加一個按鈕用來改變標簽的顯示。在Library窗口中找到類型為UIButton的Round Rect Button對象,將它拖到窗口里,并放在標簽下面。
4)將按鈕加入設計界面后,雙擊按鈕進入編輯模式,將按鈕的文本改為“Say Hello”。
5)保存xib文件后,返回MonoDevelop并運行應用程序。
當應用程序在模擬器中運行時,會看到添加的按鈕和標簽。觸碰(實際只能單擊,因為是在模擬器上運行的)按鈕,會看到按鈕的背景顏色變成了藍色,但什么也沒有發生。要在觸碰按鈕時改變標簽的文本,還要為按鈕編寫相應的代碼。準備好,繼續!
1.2.2 添加outlet
IB不像常用的微軟開發工具那樣支持類代碼生成。要在IB中定義的視圖與代碼之間實現交互,需要使用outlet,它可在代碼中引用在xib文件中定義的對象。雖然需要一些手動步驟來完成該工作,但很快就會熟悉。而且,通過C#語言(尤其是局部類)與MonoTouch設計工具相結合,實際接觸的代碼比在使用objective-C和Xcode時要少很多。現在,回到IB。
在IB中,需要為示例創建兩個outlet,一個用于按鈕,以便訂閱其事件;另一個用于標簽,以便通過程序來修改它的文本。下面先創建標簽的outlet,在Library窗口中選擇Classes標簽頁,然后在列表中選擇AppDelegate。最后,如圖1-12所示,選擇AppDelegate之后,在顯示的Library窗口下半部分區域選擇Outlets。
AppDelegate是一個類,其作用是接收由UIApplication操作所觸發的調用,例如應用程序啟動完成(有點類似回調接口,不過并不完全相同)。這里,“委托”(Delegate)并不是.NET中所熟悉和喜愛的委托,而是整個IOS SDK中常用的Objective-C技術。MonoTouch支持Objective-C 的Delegates(委托),將該委托抽象化,讓C#和C# Delegates(委托)都可以對它進行訪問。如果暫時無法理解這個概念也不要緊,第2章會詳細講述它。現在,只需要知道在應用程序中可通過AppDelegate類訪問按鈕和標簽就可以了,因此需要在AppDelegate中為它們創建outlet。
要將UILabel的outlet添加到AppDelegate中,單擊Library窗口左下角的+按鈕添加一個outlet,將它的默認的名字myOutlet1修改為HelloLabel。新outlet的類型(Type)的默認值是id,它的值也可以是任何的NSObject,和C#的對象有點類似,將該值改為UILabel,這樣就可將標簽連接到outlet了(下面要做的事),而且只能連接到UILabel,不能是其他對象。完成后,將會看到如圖1-13所示的Library窗口。
回顧一下剛才所做的,會給有微軟開發經驗的用戶帶來非常不同的用戶體驗。現在,有了保存用戶界面顯示所需要的所有序列化對象的xib文件,有了實現用戶界面對象之間交互的代碼,而要將xib中的對象與代碼連接起來,需要在IB的AppDelegate中為UILabel添加outlet。剩下的工作就是將UILabel連接到剛剛定義的outlet,而這將會在C#中創建一個指向UILabel的屬性。
要連接窗口中的UILabel與AppDelegate中的UILabel outlet,在MainWindow.xib窗口中選擇AppDelegate,然后在主菜單中打開Connections Inspector (Tools→Connections Inspector)窗口。在Outlet區域中,會看到剛才創建的HelloLable outlet。單擊Connections Inspector中outlet右邊的圓形圖標,并按住鼠標鍵(如果是多按鈕鼠標,按住鼠標左鍵),將它拖到窗口的標簽上。按住鼠標鍵將鼠標指針移動標簽上面,會看到標簽的顏色變成了藍色,這說明它的屬性類型沒有錯,是outlet定義的UILabel類型。如果拖動到按鈕上,就不會有提示表明該控件可以與outlet連接。這是因為之前將outlet的類型由id改為UILabel了,如果不修改,類型還是id,outlet就可以連接任何控件。這就留下了一個隱患,有可能做出錯誤的連接。在標簽上松開鼠標按鈕即可建立連接。下面講述在MonoDevelop中會觸發什么事件,不過,要先完成按鈕的連接。重復之前的步驟將按鈕連接到outlet。這次,outlet的名稱為SayHellButton,類型為UIButton。重復之前的拖放操作,這次的目標是窗口中的UIButton。請注意,也可以將outlet拖動到MainWindow.xib窗口的元素上進行連接(這也是為什么要保留樹形視圖的原因),因為它們都代表著相同的對象。如果元素在窗口的初始狀態是隱藏的,就會相當方便。將IB中完成的操作保存。此時,應用程序所需要的東西已經準備完畢,可通過代碼實現對象串之間的交互了(如圖1-14所示)。
現在開始把注意力集中到代碼上。首先,先看一下在IB中保存所有東西后,MonoDevelop如何響應所有這些outlet。在MonoDevelop中,展開Solution Explorer的MainWindow.xib,打開MainWindow.xib.designer.cs文件,將看到代碼清單1-1所示的代碼。在代碼中定義了一個局部類,包含了所有在IB中創建的outlet連接。這里看到的是AppDelegate類的一部分類,包括為IB中每一個連接所創建的多個屬性。此外,要注意使用Connect特性(attributes)來聲明這些屬性(properties)。這些都是MonoTouch為代碼連接到IB中的outlet所要做的。最后要注意的是AppDelegate類的Register特性,MonoTouch會使用它在Objective-C運行時注冊一個類。
注意 嚴格地說,MonoTouch會自動注冊NSObject的子類。默認情況下,它使用Full.Namespace.Typemape這樣的格式來注冊子類。特性的作用就是將注冊類名映射成“簡寫名稱”(ShortName);否則,MonoTouch.UIKit.UIButton就連接不到UIButton。
代碼清單1-1 MainWindow.xib.designer.cs // // <autogenerated> // This code was generated by a tool. // Mono Runtime Version: ... // // Changes to this file may cause incorrect behavior and // will be lost if the code is regenerated. // </autogenerated> // namespace LMT12 {// Base type probably should be MonoTouch.Foundation.NSObject or// subclass[MonoTouch.Foundation.Register("AppDelegate")]public partial class AppDelegate{private MonoTouch.UIKit.UIWindow __mt_window;private MonoTouch.UIKit.UIButton __mt_SayHelloButton;private MonoTouch.UIKit.UILabel __mt_HelloLabel;#pragma warning disable 0169[MonoTouch.Foundation.Connect("window")]private MonoTouch.UIKit.UIWindow window {get {this.__mt_window = ((MonoTouch.UIKit.UIWindow)(this.GetNativeField ("window")));return this.__mt_window;}set {this.__mt_window = value;this.SetNativeField ("window", value);}}[MonoTouch.Foundation.Connect("SayHelloButton")]private MonoTouch.UIKit.UIButton SayHelloButton {get {this.__mt_SayHelloButton = ((MonoTouch.UIKit.UIButton)(this.GetNativeField ("SayHelloButton")));return this.__mt_SayHelloButton;}set {this.__mt_SayHelloButton = value;this.SetNativeField ("SayHelloButton", value);}}[MonoTouch.Foundation.Connect("HelloLabel")]private MonoTouch.UIKit.UILabel HelloLabel {get {this.__mt_HelloLabel = ((MonoTouch.UIKit.UILabel)(this.GetNativeField ("HelloLabel")));return this.__mt_HelloLabel;}set {this.__mt_HelloLabel = value;this.SetNativeField ("HelloLabel", value);}}} }打開Main.cs文件,會看到局部類AppDelegate的另一部分代碼。這里可以添加響應按鈕的TouchUpInside事件的代碼,并改變標簽的文本,詳細代碼請看代碼清單1-2。
保存后,運行應用程序。當應用程序在模擬器中運行后,單擊按鈕,并注意標簽上文本的變化。可以看到,標簽尺寸太小,容納不了全部文本,因而在文本的末尾使用了省略號代替(其實,這是故意的,目的是為了講述將要在IB中做的事)。現在,返回IB,修正這個問題。
注意 在IB和MonoDevelop之間來回切換是很常見的事,因而盡早熟悉有好處。
返回IB,在窗口中選擇UILabel并通過拉伸增加它的寬度。如圖1-15所示,IB會顯示Guide Geometry來協助調整大小和布局,以符合蘋果人機界面指南(Human Interface Guideline,HIG)。
然后,設置標簽文本居中顯示。選擇標簽,打開Attributes Inspector(Tools→ Attribures Inspector),在Attribures Inspector布局區域,設置文本的排列(alignment)為居中(centered)。保存修改并返回MonoDevelop運行應用程序。單擊按鈕,這次就可在標簽內看到全部文本了。
如果回頭再看MonoDevelop,也許希望它能生成一些代碼反映剛才對標簽所做的改動。然而,IB不會生成代碼,它會將它內部的改動直接序列化到xib文件中。在整個過程中,只有鉤上(hook)outlet的屬性才會生成代碼,而且是在MonoDevelop觀察到xib文件發生改動時創建的。代碼清單1-3列出了xib文件中反映標簽變化的代碼,節點表示增大后標簽的尺寸。
返回MonoDevelop并運行應用程序,單擊按鈕,這次會看到“Hello MonoTouch”已經全部顯示出來了。值得慶賀,終于完成了這個簡單的Hello World示例。現在已經可以在模擬器中看到應用程序的運行情況了,下一步要做的是將它移植到設備上進行開發。
總結
以上是生活随笔為你收集整理的《MonoTouch开发实践指南》一1.2 创建MonoTouch应用程序的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 中国高性能计算机TOP100出炉 曙光联
- 下一篇: 表空间检测异常的问题诊断