IBOutletCollection

一開始我們在學寫 Cocoa 應用程式的時候,我們學到,當你用 Interface Builder(以下簡稱 IB) 拉完了各種介面-視窗、選單、按鈕-之後,接著,在你的 controller class 中要控制某個 IB 產生的介面元素-假設是一個按鈕,你要產生一個 IBOutlet 成員變數,在 IB 裡頭把成員變數與這個拉出來的按鈕連結起來。按下按鈕要做什麼事情,則要建立一個 IBAction 的介面,繼續在 IB 裡頭連結,最後在 .m 或 .mm 檔案中完成實作。一個 IBOutlet 連結到一個 UI 物件,一個 UI 物件連結到一個 IBAction,一個對一個。

後來我們有了 iPhone。在 iPhone SDK 裡頭,一個按鈕就可以連結不只一個 IBAction,你可以透過 addTarget:action:forControlEvents: 不斷增加指定要負責做事的 class 與拿來做事的 method。一個按鈕按下去,會同時做許多件事情。事情有了變化了,不再只是一對一,而是一對多。

現在我們有了 iOS 4.0,就更從一對多,變成多對多了。iOS 4.0 的 SDK 多了一個新的關鍵字,叫做 IBOutletCollection,於是你可以將一個單一的成員變數,連結到許多的 UI 元件的實體上。

或這麼說,以前如果想要在我們的 iPhone 程式裡,在某個畫面中,放置四個標籤元件(UILabel),然後想要改變這些標籤中的文字內容,我們會在 header 裡頭這樣宣告:

@interface MyViewController : UIViewController {
	UILabel *label1;
	UILabel *label2;
	UILabel *label3;
	UILabel *label4;
}

@property (retain, nonatomic) IBOutletCollection UILabel *label1;
@property (retain, nonatomic) IBOutletCollection UILabel *label2;
@property (retain, nonatomic) IBOutletCollection UILabel *label3;
@property (retain, nonatomic) IBOutletCollection UILabel *label4;
@end

然後分別連結這四個 label。而現在,你可以這樣宣告:

@interface MyViewController : UIViewController {
	NSArray *labels;
}
@property (retain, nonatomic) IBOutletCollection (UILabel) NSArray *labels;
@end

在 IB 中,只要是 UILabel 類別的物件,都可以與 lables 連結。接著,你就可以用任何可以對 NSArray 的操作方式,處理畫面中的 UI 元件,比方說,你可以用點 KVC,直接用一行程式碼,就改變多個 UILabel 的文字內容,像這樣-

[labels setValue:@"1234" forKeyPath:@"text"];

蘋果官方文件中對這方面的說明,請參見 Interface Builder 手冊中,Xcode Integration 這一節。其實呢,寫這一篇東西,只是單純想要摘錄文件中的這一段-

In Mac OS X and iPhone OS v3.3 and earlier, you can connect an outlet to only a single object. However, starting with iPhone OS v3.4, you can connect an outlet to multiple objects. To do so, use the IBOutletCollection keyword.

在 3.2 版到 4.0 版之間,iPhone OS 什麼時候推出 3.3 與 3.4 版了?

One thought on “IBOutletCollection

Comments are closed.