2011-03-27 59 views
0

我知道還有類似的問題,但批准的答案似乎不適用於我。所以,我的方案是我有一個UITableView,我想通過掃描條形碼來添加和刪除項目。所有的工作正常,但我不能讓UITableView顯示更新的信息。該問題具體來自tableView:cellForRowAtIndexPath:方法在最初的一次之後的每次重新加載中。更具體地說,該單元始終是而不是nil,因此它跳過了新的單元創建邏輯。UITableView如何在reloadData上創建UITableViewCell的問題

對於像我這樣的其他問題,答案是單元標識符是問題。那麼,我試着搞亂了它,它沒有奏效。這裏是我的代碼:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    UITableViewCell *cell = nil; 

    if (indexPath.section < vehicle.inventoryCategoriesCount) { 
     cell = [tableView dequeueReusableCellWithIdentifier:@"ModelCell"]; 

     if (cell == nil) { 
      cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"ModelCell"] autorelease]; 

      NSString *model = [[[vehicle.inventory filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"category == %@", [vehicle.inventoryCategories objectAtIndex:indexPath.section]]] valueForKeyPath:@"@distinctUnionOfObjects.model"] objectAtIndex:indexPath.row]; 

      cell.textLabel.text = model; 
      cell.detailTextLabel.text = [NSString stringWithFormat:@"%d", [[vehicle.inventory filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"model == %@", model]] count]]; 
      cell.selectionStyle = UITableViewCellSelectionStyleNone; 
     } 
    } else { 
     cell = [tableView dequeueReusableCellWithIdentifier:@"RemoveCell"]; 

     if (cell == nil) { 
      cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"RemoveCell"] autorelease]; 

      cell.textLabel.text = @"Remove an Item"; 
      cell.textLabel.textColor = [UIColor redColor]; 
      cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 
     } 
    } 

    return cell; 
} 

因此,在此示例代碼中,我有一個單獨的章節兩個不同的小區標識。它們是ModelCellRemoveCell。那麼,他們不會作爲解決方案工作,因爲沒有任何反應。如果我在分配新單元格時更改單元格標識符,它會起作用,因爲它僅僅是擦除了所有內容,因爲標識符不匹配,但我會認爲這是錯誤的,並且應該有更好的解決方案問題或我根本沒有做正確的事情。

我會很感激這方面的幫助。我已經花了一天的時間在這段代碼到目前爲止,我沒有得到任何地方,我想要得到它的修復和移動到我的應用程序的其他部分...

在此先感謝您的任何幫助!

UPDATE

由於@fluchtpunkt的問題已經解決。對於將來可能遇到此問題的其他人,這裏是更正後的代碼。我決定通過附加節號來使標識符更加獨特。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    UITableViewCell *cell = nil; 

    if (indexPath.section < vehicle.inventoryCategoriesCount) { 
     NSString *identifier = [NSString stringWithFormat:@"ModelCell-%d", indexPath.section]; 

     cell = [tableView dequeueReusableCellWithIdentifier:identifier]; 

     if (cell == nil) { 
      cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:identifier] autorelease]; 

      cell.selectionStyle = UITableViewCellSelectionStyleNone; 
     } 

     NSString *model = [[[vehicle.inventory filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"category == %@", [vehicle.inventoryCategories objectAtIndex:indexPath.section]]] valueForKeyPath:@"@distinctUnionOfObjects.model"] objectAtIndex:indexPath.row]; 

     cell.textLabel.text = model; 
     cell.detailTextLabel.text = [NSString stringWithFormat:@"%d", [[vehicle.inventory filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"model == %@", model]] count]]; 
    } else { 
     cell = [tableView dequeueReusableCellWithIdentifier:@"RemoveCell"]; 

     if (cell == nil) { 
      cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"RemoveCell"] autorelease]; 

      cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 
      cell.textLabel.textColor = [UIColor redColor]; 
     } 

     cell.textLabel.text = @"Remove an Item"; 
    } 

    return cell; 
} 

UPDATE

最終代碼的版本,糾正我如何標識作品的誤解。我想我會保持簡單,所以我在單元格樣式類型之後命名標識符。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    UITableViewCell *cell = nil; 

    if (indexPath.section < vehicle.inventoryCategoriesCount) { 
     cell = [tableView dequeueReusableCellWithIdentifier:@"Value1"]; 

     if (cell == nil) { 
      cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"Value1"] autorelease]; 

      cell.selectionStyle = UITableViewCellSelectionStyleNone; 
     } 

     NSString *model = [[[vehicle.inventory filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"category == %@", [vehicle.inventoryCategories objectAtIndex:indexPath.section]]] valueForKeyPath:@"@distinctUnionOfObjects.model"] objectAtIndex:indexPath.row]; 

     cell.textLabel.text = model; 
     cell.detailTextLabel.text = [NSString stringWithFormat:@"%d", [[vehicle.inventory filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"model == %@", model]] count]]; 
    } else { 
     cell = [tableView dequeueReusableCellWithIdentifier:@"Default"]; 

     if (cell == nil) { 
      cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Default"] autorelease]; 

      cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 
      cell.textLabel.textColor = [UIColor redColor]; 
     } 

     cell.textLabel.text = @"Remove an Item"; 
    } 

    return cell; 
} 
+0

使CellIdentifier「更獨特」使事情變得更糟。相似的單元應該具有相同的標識符。所有'UITableViewCellStyleValue1'應該有相同的標識符。所有的'UITableViewCellStyleDefault'都應該有相同的值(但當然是不同於Value1的單元格)。小區標識符標識小區的類型,而不是它的位置。如果忽略內容,section0中的單元格與section1中的單元格完全相同。如果滾動並且tableview將section0中的單元格移出屏幕以顯示section1中的單元格,則無需創建新單元格。 – 2011-03-27 23:17:59

+0

我明白了,我誤解了標識符是如何工作的。我認爲標識符是每節。感謝您的解釋。 – Gup3rSuR4c 2011-03-27 23:19:55

回答

3

把你的配置if (cell == nil) { ... }的以外,如果條件是唯一真正的,如果沒有電池可以循環使用。你一定想重用你的單元格。所以當你有一個有效的單元格時配置它們。

像這樣:

if (indexPath.section < vehicle.inventoryCategoriesCount) { 
    cell = [tableView dequeueReusableCellWithIdentifier:@"ModelCell"]; 

    if (cell == nil) { 
     // only create a new cell if a dequeue was not successful. 
     cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"ModelCell"] autorelease]; 
    } 
    // whatever happened before you have a valid cell here. 

    // configure cell: 
    NSString *model = [[[vehicle.inventory filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"category == %@", [vehicle.inventoryCategories objectAtIndex:indexPath.section]]] valueForKeyPath:@"@distinctUnionOfObjects.model"] objectAtIndex:indexPath.row]; 

    cell.textLabel.text = model; 
    cell.detailTextLabel.text = [NSString stringWithFormat:@"%d", [[vehicle.inventory filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"model == %@", model]] count]]; 
    cell.selectionStyle = UITableViewCellSelectionStyleNone; 
} 

如果你想優化你的代碼,你可以移動是爲 (cell == nil)條件內的每一個細胞相同的選項

。例如設置selectionStyle,或改變文字顏色

+0

但是;這樣做,不會每個細胞都有相同的標籤,細節和選擇風格嗎?那些init應該在willDisplayCell上,我錯了嗎? – Oliver 2011-03-27 22:44:21

+0

嗯,這是一個非常簡單的解決方案,但現在我看到了我陷入困境的地方。我已經在上面發佈了我的更新代碼,以供將來遇到此問題的任何人使用。謝謝@fluchtpunkt! – Gup3rSuR4c 2011-03-27 22:59:21

+0

@Oliver你是如何得出這個結論的?此方法針對出現在tableView中的每個單元格調用,而text和detailText不同,因爲所有單元格都有不同的索引路徑。 – 2011-03-27 23:09:10

0

亞歷克斯 - 如果我看你就在上面的代碼,你這樣做是:

cell = [tableView dequeueReusableCellWithIdentifier:@"ModelCell"]; 

然而,所有的例子(和我的代碼)需要一個靜態的NSString的CellIdentifier

static NSString *MyIdentifier = @"MyIdentifier"; 
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier]; 

然後這工作的預期方式。

0

您肯定會重用您的單元格。如果你把你的配置放在if(cell == nil)中,它在沒有單元被重用時工作。所以請在if(cell == nil)條件之外加上以下代碼片段------------

if(cell == nil) {`` //在此輸入代碼NEMString * model = [[[vehicle.inventory filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@「category ==%@」,[vehicle.inventoryCategories objectAtIndex:indexPath.section]]] valueForKeyPath:@「@ distinctUnionOfObjects.model」] NSString * model = [[[vehicle.inventory filteredArrayUsingPredicate:[NSPredicate predicateWithFormat: objectAtIndex:indexPath.row];

 cell.textLabel.text = model; 
     cell.detailTextLabel.text = [NSString stringWithFormat:@"%d", [[vehicle.inventory filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"model == %@", model]] count]]; 
     cell.selectionStyle = UITableViewCellSelectionStyleNone; 
相關問題