2012-11-01 33 views
81

我試圖解決如何在iOS 6中使用UITableView的新方法時設置UITableViewCellStyle使用iOS 6時UITableViewCell的設置風格UITableView dequeueReusableCellWithIdentifier:forIndexPath:

以前,在創建UITableViewCell時,我會更改UITableViewCellStyle枚舉,以在調用initWithStyle:時創建不同類型的默認單元格,但從我可以收集的內容中,不再是這種情況。

蘋果文檔UITableView規定:

返回值: 與相關聯的重用標識符一個UITableViewCell對象。此方法始終返回有效的單元格。

討論: 出於性能原因,一個表視圖的數據源通常應該重用的UITableViewCell對象時將其分配細胞在其的tableView行:的cellForRowAtIndexPath:方法。表視圖維護數據源標記爲可重用的UITableViewCell對象的隊列或列表。當被要求提供表格視圖的新單元格時,從數據源對象調用此方法。此方法將取出現有單元格(如果有),或根據您之前註冊的類或nib文件創建新單元格。

重要:調用此方法之前的方法:你必須註冊使用registerNib類或筆尖文件:forCellReuseIdentifier:或的registerClass:forCellReuseIdentifier。

如果您爲指定的標識符註冊了一個類並且必須創建一個新的單元格,則此方法通過調用其initWithStyle:reuseIdentifier方法來初始化該單元格。對於基於筆尖的單元格,此方法從提供的nib文件加載單元格對象。如果現有單元可供重用,則此方法將調用單元的prepareForReuse方法。

這是我的新cellForRowAtIndexPath看起來如何實施新方法後:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString *cellIdentifier = @"cell_identifier"; 

    [tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:cellIdentifier]; 

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath]; 

    return cell; 
} 

我到目前爲止的代碼工作正常,但總是返回默認樣式。如何更改此設置,以便我可以使用其他樣式創建單元格,例如UITableViewCellStyleDefault,UITableViewCellStyleValue1UITableViewCellStyleValue2UITableViewCellStyleSubtitle

我不想要子類UITableViewCell,我只是想改變默認類型,因爲我可以在iOS 6之前做。看起來很奇怪的是,蘋果會提供增強的方法,但用最少的文檔來支持它們的實現。

有沒有人掌握了這個,或遇到類似的問題?我努力尋找任何合理的信息。

回答

103

我知道你說你不想創建一個子類,但它看起來不可避免。基於同時在iOS的6.0模擬器測試彙編代碼,UITableView通過執行

[[<RegisteredClass> alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:<ReuseIdentifier>] 

換句話說創建的UITableViewCell(或它的子類)的新實例,發送(UITableViewCellStyleDefault)樣式似乎硬編碼的。爲了解決這個問題,你需要創建覆蓋缺省初始化initWithStyle:reuseIdentifier:,並傳遞您希望使用的樣式子類:

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier 
{ 
    // ignore the style argument, use our own to override 
    self = [super initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:reuseIdentifier]; 
    if (self) { 
     // If you need any further customization 
    } 
    return self; 
} 

而且,它可能是更好的viewDidLoad發送registerClass:forCellReuseIdentifier:,而不是做它每一個單元被請求時:

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    [self.tableView registerClass:<RegisteredClass> forCellReuseIdentifier:<ReuseIdentifier>]; 
} 
+4

我開始認爲這確實是這種情況。這不是一個主要的問題,但不得不繼承'UITableViewCell'以獲得其他默認樣式是一件很痛苦的事情,因爲它只會產生不必要的文件。感謝您的評論並確認我的懷疑。 – CaptainRedmuff

+11

不要忘記,而不是子類化,你可以使用舊的iOS5方法,這仍然有效。這樣你可以初始化你想要的任何類型的單元格樣式。見另一個答案。 – SpacyRicochet

60

dequeueReusableCellWithIdentifier不會被棄用這樣你就不會使用新的dequeueReusableCellWithIdentifier:forIndexPath:需要。

如果您使用自定義單元類,則使用新方法以及相應的註冊方法(在viewDidLoad中),但如果要使用其中一個UITableViewCellStyle枚舉,則使用舊方法。

+1

Upvoted指出,你不*必須*使用花哨的新方法。只有當它們適合你的目的或者如果替代品被棄用。 – SpacyRicochet

+0

如果你特別熱衷,可以重寫'dequeueReusableCellWithIdentifier:forIndexPath:'以提供一些以舊方式構建單元的標識符(並返回它們)。其他標識符將調用超級並返回。爲這種類型的標識符創建一個標識符的NSDictionary到構造塊可能是有意義的。 – Benjohn

11

可以使用故事板界面生成器避免外來亞類:

  1. 在故事板視圖中,選擇表視圖細胞原型細胞(在表視圖)
  2. 在公用事業視圖中,在屬性檢查員,修改樣式值
  3. (任選地)修改其他值,諸如選擇與附件

新的IOS 6.0 dequeueReusableCellWithIdentifier:forIndexPath:在分配新單元格並返回時使用這些值。 (使用Xcode 4.5.2進行iOS 6.0編譯測試)

6

保存一個文件的另一種方法是創建一個Nib並使用registerNib:forCellReuseIdentifier:代替。

製作筆尖很簡單:在Interface Builder中創建一個新的.xib文件。刪除默認視圖。添加一個Table View Cell對象。使用屬性檢查器,更改單元格的樣式。 (在這裏,你也有機會通過調整其他屬性進一步自定義單元格。)

然後在您的表視圖控制器的viewDidLoad方法調用是這樣的:

[self.tableView registerNib:[UINib nibWithNibName:@"StyleSubtitleTableCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:@"Cell"]; 
+0

initWithStyle:不調用reuseIdentifier。 – thierryb

-5

我對這個解決方法是調用initWithStyle: reuseIdentifier:後我已經使用[self.tableView dequeueReusableCellWithIdentifier:@"cellId" forIndexPath:indexPath]獲得了它。畢竟,init只是另一個選擇器,編譯器不會在已經初始化的對象上調用它。然而,它會抱怨沒有使用初始化調用的結果,所以我做的:

UITableViewCell* cell = [self.tableView dequeueReusableCellWithIdentifier:@"cellId" forIndexPath:indexPath]; 
cell = [cell initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"cellId"]; 

我想這不會在雨燕工作...

+0

這在Swift中正常工作。 – faraquet99

+0

最優雅的解決方案。希望initWithStyle的膽量不會再重新創建。 –

+2

好吧,我猜如果你這樣做,你可以放棄離隊的東西... – stk

0

Bolot的答案是正確的。簡單,你不需要創建任何XIB文件。

我只是想更新他對任何人使用,而不是斯威夫特的Objective-C的做這件事的答案:

override init(style: UITableViewCellStyle, reuseIdentifier: String?) { 
    super.init(style: .value1, reuseIdentifier: reuseIdentifier) 
} 

required init?(coder aDecoder: NSCoder) { 
    fatalError("init(coder:) has not been implemented") 
} 
相關問題