2011-05-10 118 views
1

我正面臨一些奇怪的問題。每當我滾動我的表格視圖時,我的數據被替換爲其他單元格。每一次,它都會被不同的單元格數據取代。我沒有看到這個替代品有任何特定的模式。滾動時顯示的單元格數據不正確UITableView

+4

您並未重複使用/正確創建單元格。發佈您的cellForRowAtIndexPath方法,我們將能夠指出錯誤 – Vladimir 2011-05-10 15:07:35

+3

需要查看'tableView:cellForRowAtIndexPath:'的代碼。 – PeyloW 2011-05-10 15:10:10

回答

7

下面是如何正確地重用單元代碼:

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

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
    if (cell == nil) {   
     cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; 
    } 

    // Configure the cell... 
    cell.textLabel.text = [array objectAtIndex:indexPath.row]; 

    return cell; 
} 

如果您提供的代碼,我們可以修改,而不是給你普通的例子。

+0

嗨,謝謝你的答覆。但是如果我在單元格分配行之後完成了if(cell == nil)的括號,我的日期會相互重疊。 – user714236 2011-05-10 18:16:10

+0

@user如果你的日期相互重疊,那是因爲你沒有正確處理日期。這是處理可重用細胞的正確方法。如果你認真尋求幫助,你應該發佈一些代碼。我的猜測是,您要麼每次添加新的子視圖,要麼手動繪製它們,您在繪製日期之前未清除表面。 – 2011-05-10 21:41:23

+0

這不僅是單元重用的問題。在iOS 6.0中,有一個很好的方法來解決這個問題:http://stavash.wordpress.com/2012/12/14/advanced-issues-asynchronous-uitableviewcell-content-loading-done-right/ – Stavash 2012-12-14 16:07:12

4

如果您創建了自定義單元格,則可能必須在UITableViewCell子類上實施prepareForReuse以清除單元格數據。

7
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil] autorelease]; 
+0

Thanks Rams.I得到了解決方案。我沒有給複用標識符,它對我來說非常完美。 – user714236 2011-05-17 14:37:54

+1

yes this reuseIdentifier:nil也幫助我.. – 2012-09-27 10:29:01

+0

非常感謝你的工作。我的細胞每次都在變化。 – 2013-12-22 13:49:46

0

舊的,但仍然... 我遇到了這個問題。如果其他人有一天看到這個問題。 我沒有注意到,也不記得我爲什麼這麼做,但是我寫了測試if (cell == nil)裏面的單元格的配置,而不是在寫完之後寫入它。我一定累了這一天...

1

我在iOS 7和故事板上有同樣的問題,而我從來沒有在老年人Xcode-SDK版本上使用相同的代碼的這個問題,並嘗試從stackoverflow很多建議,我無法修復它,並猜測是什麼?!蘋果的TableView Programming Guide有很好的解釋指南。 甚至不需要使用cell==nil

所以要創建一個使用故事板的自定義tableview單元格,可以正確重用,可以採取兩種不同的方法。我個人更喜歡第一個更直接的,但我把這兩個解決方案放在這裏。

第一種方法

  1. 創建一個使用主從應用模板的項目,並選擇使用故事板選項。
  2. 在故事板畫布上,選擇主視圖控制器。
  3. 在Identity檢查器中,驗證Class是否設置爲自定義MasterViewController類。
  4. 選擇主視圖控制器內部的表格視圖。
  5. 在屬性檢查器中,驗證內容彈出式菜單是否設置爲動態原型。
  6. 選擇原型單元格。
  7. 在屬性檢查器中,在樣式彈出菜單中選擇自定義。
  8. 在標識符文本字段中輸入重用標識符。 這是與發送到dequeueReusableCellWithIdentifier:消息中的表視圖相同的重用標識符。
  9. 在Accessory彈出菜單中選擇Disclosure Indicator。
  10. 將庫中的對象拖動到單元格上。 對於此示例,拖動兩個標籤對象並將它們放在靠近單元格末端的位置(爲附件視圖留出空間)。
  11. 選擇對象並設置其屬性,大小和自動修改特徵。

爲此過程的編程部分設置的一個重要屬性是每個對象的tag屬性。在Attributes inspectorView部分中查找此屬性,併爲每個對象分配一個唯一的整數。

現在編寫您通常會寫入的代碼以獲取表視圖的數據。 (在本例中,您需要的唯一數據是每個單元格的行號。)實現數據源方法tableView:cellForRowAtIndexPath:從原型創建一個新單元格,並使用數據填充它,其方式與此代碼類似:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyIdentifier"]; 

    UILabel *label; 

    label = (UILabel *)[cell viewWithTag:1]; 
    label.text = [NSString stringWithFormat:@"%d", indexPath.row]; 

    label = (UILabel *)[cell viewWithTag:2]; 
    label.text = [NSString stringWithFormat:@"%d", NUMBER_OF_ROWS - indexPath.row]; 

    return cell; 
} 

有此代碼的幾個方面需要注意:

  • 分配給原型電池的串標識符是你傳遞給在dequeueReusableCellWithIdentifier:表視圖相同的字符串。
  • 因爲原型單元格是在故事板中定義的,所以dequeueReusableCellWithIdentifier:方法總是返回一個有效的單元格。您無需檢查返回值nil並手動創建單元格。
  • 代碼通過調用viewWithTag:傳入其標籤整數來獲取單元中的標籤。然後它可以設置標籤的文本內容。

第二種方法

如果你不喜歡使用標籤,您可以使用另一種方法設置單元格中的內容。爲要設置的對象定義一個帶有插座屬性的自定義UITableViewCell子類。在故事板中,將新類與原型單元相關聯,並將出口連接到單元中的相應對象。

要使用網點的自定義單元格內容

  1. 名爲MyTableViewCell的Objective-C類添加到您的項目。
  2. 下面的代碼添加到所述接口中MyTableViewCell.h

    @interface MyTableViewCell:的UITableViewCell

    @屬性(非原子,弱)IBOutlet中的UILabel * firstLabel; @property(非原子,弱)IBOutlet UILabel * secondLabel; @end

  3. 下面的代碼添加到實施MyTableViewCell.m

    @synthesize firstLabel,secondLabel;

  4. 下面的代碼行添加到實現該數據源的源文件:

    #進口「MyTableViewCell。H」

  5. 使用Identity inspector原型細胞的類設置爲MyTableViewCell

  6. 使用連接檢查員在原型細胞中的兩個出口連接到其相應的標籤。 enter image description here

  7. 執行數據源方法tableView:cellForRowAtIndexPath:

    -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    MyTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyIdentifier"]; 
    
    cell.firstLabel.text = [NSString stringWithFormat:@"%d", indexPath.row]; 
    cell.secondLabel.text = [NSString stringWithFormat:@"%d", NUMBER_OF_ROWS - indexPath.row]; 
    
    return cell; 
    } 
    

代碼使用訪問器方法獲取對單元中標籤的訪問權限(此處使用點標記)。代碼然後可以設置標籤的文本內容。

相關問題