2013-06-18 43 views
7

我無法理解這是如何工作的。我已經閱讀了關於它的許多線索 - 例如UITableView dequeueReusableCellWithIdentifier TheoryHow does dequeueReusableCellWithIdentifier: work?瞭解UITableView dequeueReusableCellWithIdentifier - 即使在第一次調用時也返回單元格

但是,即使在第一次加載時,我的UITableView每次都會成功地將某個單元出隊(它永遠不會爲零)。我的印象是,類似的單元格應該使用相同的標識符,所以你只需要改變必要的東西。

因爲

if (!cell) { 
    NSLog(@"New cell"); 
    cell = [[UITableViewCell alloc] initWithStyle:someStyle reuseIdentifier:someIdentifier]; 
} 

不會被調用,我不知道我應該如何處理細胞與不同風格的同桌,因爲風格只能在初始化設置。

我也嘗試過使用不同的單元格標識符,以確保它不會重複使用來自不同表格或其他東西的單元格。我正在使用[tableView registerClass: forCellReuseIdentifier:]

註冊這些標識符如果我明白了,此方法應該只返回先前創建的已移出屏幕(隱藏,即可重用)的單元格。那麼它是如何在第一次被叫時返回一個單元呢?


編輯:所以混淆使用[tableView dequeueReusableCellWithIdentifier: forIndexPath:]代替[tableView dequeueReusableCellWithIdentifier:](第一要求註冊標識符,所述第二將返回nil如果沒有可用的 - 的行爲我上面期待)。

但是,我注意到當我將代碼更改爲使用[tableView dequeueReusableCellWithIdentifier:]時,它創建了一個新的單元格,其contentView.frame的寬度爲320(全寬)。之前,當我做了dequeue...forIndexPath它會給出302的寬度,或者單元格的視覺/「真實」寬度。爲什麼是這樣?

此外,有沒有一種方法來指定UITableViewCells regstiered的樣式重用?


解決方案:所以我發現這個線程UITableView cell.contentView.bounds.size.width Changes With Cell Reuse,它說,當你設置autoresizingmask到UIViewAutoresizingFlexibleLeftMargin,當你嘗試做相對定位它是固定的(在內容查看寬度是最初的完全寬度,但是當你目前它縮小了,所以如果你做了計算,它仍然會正常顯示)。

我在右邊定位了一個UISwitch - 當我設置自動調整屏蔽時,它首先顯示,但是當我切換時它會移動另外的20個像素。我不知道是什麼導致了額外的轉換,但我最終通過簡單地將UISwitch設置爲單元的附件視圖來解決它。

(這是部分偏離原來的問題,但如果有人絆倒這可能會有用)。對於任何人想知道的原始問題,答案是在第一次編輯。

+1

您的單元格是從故事板創建到UITableViewController中的嗎? – danypata

+0

所有以編程方式創建...是啊,很多人都說使用故事板...但我還沒有習慣它,而且我覺得我會更好地理解它,知道什麼是真正理解 – Raekye

+1

沒有問題,但我想知道,因爲當你從故事板創建單元格到UITableViewContoller時,'deque '方法總是會返回一個有效的單元格(如果使用了正確的標識符) – danypata

回答

8

當您撥打[tableView registerClass: forCellReuseIdentifier:]時,您正在教授表格視圖,稍後您將使用指定的ReuseIdentifier時該怎麼做。所以,當你再打[tableView dequeueReusableCellWithIdentifier:]它要麼:

A.獲取先前已經被創建,而不是當前正在使用

OR

B.創建類的一個新小區的小區您指定

所以,當你出列,你總是會得到一個實例。如果你想用initWithStyle:reuseIdentifier:自己創建新的單元格實例,那麼你不應該在表格視圖中註冊一個類。或者,保留註冊並添加邏輯來指定需要配置的所有內容(並考慮使用多個不同的單元類並重用標識符)。

+1

如果我取出'[tableView registerClass:forCellReuseIdentifier:]',我得到一個「NSInteralInconsistencyException:無法使標識符[我的標識符]出隊」。當我做註冊時,它總是返回一個單元格,即使我使用不同的標識符,所以我不能創建不同的單元格樣式 – Raekye

+0

您必須使用'dequeueReusableCellWithIdentifier:forIndexPath:'然後 - 它需要您註冊一個班或NIB。如果你需要更多的幫助,你可能想要顯示註冊的代碼和'tableView:cellForRowAtIndexPath:'。 – Wain

+0

是的,我剛剛注意到另一個問題。因此,使用沒有索引路徑的方法可以按預期工作,但現在還有另一個問題(更新questino) – Raekye

0

因爲第一次的細胞是零,這就是爲什麼這個被稱爲:

if (!cell) { 
NSLog(@"New cell"); 
cell = [[UITableViewCell alloc] initWithStyle:someStyle reuseIdentifier:someIdentifier]; 
} 

但這時如果電池是早已準備好了再利用,基本上它不是零 - 它返回的單元格,它不點擊以上語句

+0

問題的關鍵在於它第一次不是無 – Raekye

0

從蘋果的文檔在https://developer.apple.com/library/ios/#documentation/UIKit/Reference/UITableView_Class/Reference/Reference.html#//apple_ref/doc/uid/TP40006943

調用此方法從數據源對象時要求提供該表視圖的新細胞。此方法將取出現有單元格(如果有)或使用之前註冊的類或nib文件創建新單元格。如果沒有單元可用於重用並且未註冊類或nib文件,則此方法返回nil。

的離隊方法

  1. 返回再生細胞(如果可用)

  2. 創建一個新的細胞如果您註冊一個(你提到你這樣做)

  3. 如果這些都不是真實的,它返回nil

如果刪除登記(可以隱藏在廈門國際銀行)我猜,那麼你將獲得無結果。

+0

我沒有使用intercae構建器。我的問題的重點是它永遠不會返回零。在「回收再利用的電池」方面,應用程序第一次啓動時是否有可能再生電池? – Raekye

+0

第一個單元格未被回收,它只是由表格視圖自動創建。 – Wain

+0

是啊,謝謝,我忽略了'forIndexPath:'版本和沒有 – Raekye

-1

如果你看到UITableView.h

在iOS 6中開始,客戶可以註冊每個小區的筆尖或類。

如果全部重複利用標識被註冊,使用新 - dequeueReusableCellWithIdentifier:forIndexPath:保證返回小區實例。從新出列方法返回

實例也將返回時,他們是適當的大小。

(void)registerNib:(UINib *)nib forCellReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(5_0); 

(void)registerClass:(Class)cellClass forCellReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(6_0); 
相關問題