2012-01-19 22 views
0

我試圖在UITableViewCell中使用UITextField,如下面的代碼所示。看起來,當tableview離開屏幕時,應該在單元格中的一些數據混在一起。我認爲在使用方法後,在tableview離開屏幕之後,出現了一些問題,無法給我一個「正確的」單元格。這是什麼原因?Cocoa-Touch - UITableView dequeueReusableCellWithIdentifier給我錯誤的單元格數據

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 

    static NSString *addGroupContactCellIdentifier = @"AddGroupContactCell"; 

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:addGroupContactCellIdentifier]; 

    if (cell == nil) { 

     cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault 
             reuseIdentifier:addGroupContactCellIdentifier]; 

     if ([indexPath section] == 0) { // Group Name Section 

      cell.textLabel.text = @"Name"; 

      UITextField *groupNameTextField = [[UITextField alloc]initWithFrame:CGRectMake(80, 10, 210, 22)]; 
      groupNameTextField.textAlignment = UITextAlignmentLeft; 
      groupNameTextField.backgroundColor = [UIColor clearColor]; 
      groupNameTextField.placeholder = @"Type Group Name"; 

      //groupNameTextField.borderStyle = UITextBorderStyleLine; 
      groupNameTextField.clearButtonMode = UITextFieldViewModeWhileEditing; 
      groupNameTextField.returnKeyType = UIReturnKeyDone; 
      groupNameTextField.autocapitalizationType = UITextAutocapitalizationTypeSentences; 
      groupNameTextField.delegate = self; 

      [cell.contentView addSubview:groupNameTextField]; 

     } 

    } 

    if ([indexPath section] == 1) { // Contacts Section 

     cell.textLabel.text = [[self.selectedPeoplePickerContacts objectAtIndex:[indexPath row]] objectForKey:@"name"]; 
     cell.detailTextLabel.text = [[self.selectedPeoplePickerContacts objectAtIndex:[indexPath row]] objectForKey:@"number"]; 

    } 

    cell.accessoryType = UITableViewCellAccessoryNone; 

    return cell;  
} 

UPDATE:

所以我子類UITableViewCell但仍表現出同樣的錯誤了。現在,這是我的tableView:cellForRowAtIndexPath:代碼:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 

    static NSString *addGroupContactCellIdentifier = @"AddGroupContactCell"; 

    if ([indexPath section] == 0) { 

     UITableViewCellWithUITextField *cell = [tableView dequeueReusableCellWithIdentifier:addGroupContactCellIdentifier]; 

     if (cell == nil) { 

      //cell = [[UITableViewCellWithUITextField alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:addGroupContactCellIdentifier]; 

      cell = [[UITableViewCellWithUITextField alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:addGroupContactCellIdentifier textFieldPlaceholder:@"Type Group Name" textFieldDelegate:self]; 
     } 

     cell.selectionStyle = UITableViewCellSelectionStyleNone; 
     cell.textLabel.text = @"Name"; 

     // Need to set the UITableViewCell's textLabel properties otherwise they will cover the UITextField 
     cell.textLabel.opaque = NO; 
     cell.textLabel.backgroundColor = [UIColor clearColor]; 

     return cell; 

    } else { 

     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:addGroupContactCellIdentifier]; 

     if (cell == nil) { 

      cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault 
              reuseIdentifier:addGroupContactCellIdentifier]; 
     } 

     cell.textLabel.text = [[self.selectedPeoplePickerContacts objectAtIndex:[indexPath row]] objectForKey:@"name"]; 
     cell.detailTextLabel.text = [[self.selectedPeoplePickerContacts objectAtIndex:[indexPath row]] objectForKey:@"number"]; 

     return cell; 
    } 
} 

三EDIT(我有這似乎給我我想要的結果,現在2個不同的reuseIdentifiers):

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 

    if ([indexPath section] == 0) { // Group Name Section 

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

     if (cell == nil) { 

      cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault 
              reuseIdentifier:groupNameCellIdentifier]; 

      cell.textLabel.text = @"Name"; 

      UITextField *groupNameTextField = [[UITextField alloc]initWithFrame:CGRectMake(80, 10, 210, 22)]; 
      groupNameTextField.textAlignment = UITextAlignmentLeft; 
      groupNameTextField.backgroundColor = [UIColor clearColor]; 
      groupNameTextField.placeholder = @"Type Group Name"; 

      //groupNameTextField.borderStyle = UITextBorderStyleLine; 
      groupNameTextField.clearButtonMode = UITextFieldViewModeWhileEditing; 
      groupNameTextField.returnKeyType = UIReturnKeyDone; 
      groupNameTextField.autocapitalizationType = UITextAutocapitalizationTypeSentences; 
      groupNameTextField.delegate = self; 

      [cell.contentView addSubview:groupNameTextField]; 
     } 

     // Customization 


     return cell; 

    } else { 

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

     if (cell == nil) { 

      cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault 
              reuseIdentifier:addGroupContactCellIdentifier]; 
     } 

     // Customization 
     cell.textLabel.text = [[self.selectedPeoplePickerContacts objectAtIndex:[indexPath row]] objectForKey:@"name"]; 
     cell.detailTextLabel.text = [[self.selectedPeoplePickerContacts objectAtIndex:[indexPath row]] objectForKey:@"number"]; 

     return cell; 
    } 
} 

回答

1

子類化並非如有些人所建議的那樣必要。

但是你不能在if(cell == nil){「之內使用像」if([indexPath section] == 0){「這樣的邏輯,因爲這只是第一次創建單元格,它將被用於後續回收的其他索引。

相反,您需要使用兩個不同的CellIdentifiers,以便您爲零部分設置的單元格不會在表格中的其他位置重新使用。把你的if([indexPath section] == 0){在出隊之前,使用不同的單元格標識符來表示零部分和後面的部分單元格。

此外,請確保您在「if(cell == nil){」之外執行任何特定於indexpath的特定路徑,以便每次單元格被重新使用時都會應用它,而不僅僅是第一次創建它。

0

你是對的!這個問題肯定是由於UITableViewreusability功能。蘋果已經這麼做了,所以你可以重複使用單元格,並且它在性能方面非常出色!所以,當您嘗試上下滾動時,indexPath的值仍然相同,並且您的tableView從您在課堂上定義的cellForRowAtIndexPath中獲取數據!

解決方案:

您將需要繼承你的UITableViewCell,並在您的-(void)layoutSubviews方法添加UITextField

然後您將需要引用此CustomUITableViewCell並使用它來加載您的TableView。

的鏈接,這將有助於: Read this !

+0

我寧願不是子類UITableViewCell。但我見過其他處理它(我假設沒有打嗝)http://stackoverflow.com/q/409259/294661 –

+0

子類化是擺脫可重用性問題的唯一解決方案! – Legolas

+0

我不確定,但我想我擺脫了可重用性問題。看到我的編輯... –

0

值混淆在一起,因爲當你去離屏幕,然後重新加載再次將細胞從內表細胞dequed表池,但他們沒有以相同的順序重新加載他們以前在桌子上。請注意,即使您有一個有許多行的表格並且您將其滾動,也會發生混合。解決方案是將文本字段數據存儲在「數據源」數組中,然後配置單元格。

說明

基本上在你的代碼中有一個主要概念的缺陷:一旦你再生細胞,你不正確的配置內容(你不配置的話)。我的意思是,最初,當表格第一次顯示時,游泳池是空的。因此,每個需要顯示的新單元都是從頭開始重新創建的(而不是從池中恢復);假設您的表格可以在屏幕上顯示10個單元格,所以前10個單元格將全部從空白文本字段開始創建。 然後你開始在這些字段中輸入文本,並且所有的工作都正常。 在某個點開始滾動單元格:會發生什麼情況是頂部的所有單元格將從屏幕上消失並存儲(排隊)到表池中,並顯示其文本字段和其編輯的內容;假設你在第0行對單元格進行排隊。當一個新的單元格需要顯示在屏幕的底部時,你的代碼所做的第一件事就是嘗試使單元出隊。現在這次你在池中有一個單元格(第0行的單元格),這個單元格從池中取出並放在第11行的表格中,包括TEXTFIELD CONTENT。因此,「神奇地」你會發現在另一行11行0編輯的文本。除了從池中以稀疏的順序檢索單元格之外,所以在許多文本字段編輯和滾動之後,您將完成混合。

解決方案,這就是您的代碼中的錯誤的原因:只要單元格已被創建或dequed,配置它,即設置文本字段的內容。如何檢索文本內容?存儲在一個數組中。這就是爲什麼你的視圖控制器是一個「數據源」,因爲你的數據源來填充表格。由於這種排隊機制,將數據存儲在表中是一個錯誤。例如:


groupNameTextField.text=[myTextFieldContentArray objectAtIndex:indexPath.row]; 

另一種解決方案,但我不建議它是一個唯一的標識符分配給每個小區,即:


NSString *myCellId = [NSString stringWithFormat:@"CellID_%d_%d",indexPath.section,indexPath.row]; 

在這種情況下,所有的細胞將與被enqued不同的名字,你永遠不會混淆它們。 此解決方案大部分時間都在工作,但出於兩個原因不鼓勵: a。它不是最佳的,因爲你不重用單元,所以這會爲類似的單元需要額外的內存 b。您無法保證每個單元格都有效排隊,總而言之,這些邏輯都在表格內部,並且不會暴露給開發人員,因此您可能需要在每次需要時重新生成單元格(性能損失) 。

相關問題