2011-05-01 105 views
21

我有三個不同的UITableViews,每個都在它自己的視圖中,通過選項卡訪問。理想情況下,所有三個表都將共享相同的自定義UITableViewCell類和.xib文件。一個具有多個「文件所有者」的xib文件

我從一張表開始,將.xib的類設置爲我的自定義類,並將.xib的文件所有者設置爲表的父級UIViewController,這非常棒。所有與視圖相關的自定義代碼都在單元的類中(基於控制器設置的屬性的背景圖像,基於控制器設置的單元格屬性根據標籤所需行數的自定義單元高度等) 。

結果很好:單元負責所有的可視佈局,並響應用戶對單元控件的操作,而視圖控制器負責創建單元並設置其數據。

現在我需要重用其他表中的單元格,但是,自定義單元格的.xib具有單個文件所有者這一事實是一個問題。而不是複製.xib文件,是否有一種允許多個控制器擁有它的簡單方法?

+0

我想我沒有按照你的問題100%。你使用'UITableView'的委託方法' - (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath'? – joshpaul 2011-05-01 20:05:06

+0

@joshpaul是的。問題在於其他視圖控制器無法訪問另一個作爲所有者的控制器的.xib控件/屬性。 – 2011-05-01 20:18:50

+0

我有自定義單元格的xib'File's Owner'設置爲NSObject,'Cell'設置爲MyCustomTableViewCell。 – joshpaul 2011-05-02 16:13:33

回答

37

筆尖的文件所有者沒有嚴格執行。相反,它僅用於確定可用的出口和操作,並在Interface Builder中設置綁定。無論nib文件中設置的類如何,您都可以使用任何對象加載一個nib作爲它的文件所有者。當一個筆尖被加載時,它將向文件的所有者發送消息以重新建立綁定。如果實際的文件所有者對象不能識別這些選擇器,則會觸發「無法識別的選擇器」異常。這意味着如果你的nib將一些UITableViewCell綁定到它的File's Owner的'cell'插座,那麼任何具有'cell'屬性的對象都可以加載該nib。您只需要小心不要使用此行爲來發送無法識別的選擇器或意外的插座類。

在你的情況下,考慮創建一個單獨的UIViewController子類作爲你的筆尖的文件所有者。讓您的三個現有控制器都擴展該視圖控制器子類。這樣,它們都可以繼承nib文件所期望的同一組屬性,並且都可以安全地加載該nib,同時仍然定義它們自己的自定義行爲。

+0

啊,好主意。核心問題是其他視圖控制器無法訪問實例化的單元格的屬性;這很好地解決了這個問題。謝謝。 – 2011-05-01 20:13:20

+0

我一直在爲此工作一段時間,而且我非常接近回答我的問題。也許有一點幫助?您的建議如何實際使用的示意圖會很棒。我已經嘗試過,並且無法獲得UITableViewCell的三個不同子類在XIB中共享相同的TVCell。 – mputnamtennessee 2012-01-25 22:45:55

+3

@ mputnamtennessee,你將無法做到。從nib文件加載的視圖的類由nib本身定義。上面的答案是參考不同的控制器類從同一個nib文件加載同一個UITableViewCell的實例。這不同於嘗試從nib本身中加載在nib中找到的類的多個子類。你似乎有一個不同的問題來解決這可能是值得開一個新的問題。 – Jonah 2012-01-26 01:54:23

4

checked answerthis question討論了從nib文件加載自定義表格單元格的兩種方法,它們不需要將文件的所有者設置爲您的特定控制器。這些方法可讓您重用不同所有者的單元。

+1

感謝您將我指向這些人,他們都是按照我喜歡的方式來組織工作的好方法。不幸的是,兩者都需要對其他代碼進行重大的重組,現在我還沒有時間。我相信稍後我會爲這種選擇付費,但是,這是一種代碼業力。 :) – 2011-05-01 20:16:30

1

作爲文件所有者的「共享」超類並不總是一個好的解決方案。 記住,你可以隨時加載廈門國際銀行在您的視圖,並進行連接,而不使用出口,例如:

UIView *aView = [[NSBundle mainBundle] loadNibNamed:@"MyXibFile" owner:self options:nil] 
//Search subviews by tag. Obviously you need to set the tag on your view in MyXibFile 
UILabel *aLabel = (UILabel*)[aView viewWithTag:996]; 
UILabel *aTextField = (UITextField*)[aView viewWithTag:997]; 
aTextField.delegate = self; 
//etc... 

我不能說這是一個乾淨的解決方案,但在某些情況下可以工作好過繼承。