解決自定義UITableViewCell在瀏覽中出現數據行重複的問題

我在寫一個App的時候自定義了一個UITableViewCell,可是這個UITableView在運行的時候出現了每6行數據就循環重複顯示的問題,而直接使用cell.textLabel.text顯示是沒有這個問題,如下是我實現的代碼。數組

  
  
  
  
  1. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath  
  2.     NSInteger section = [indexPath section]; 
  3.     NSInteger row = [indexPath row]; 
  4.     UITableViewCell *cell; 
  5.  
  6.     switch (section) 
  7.     { 
  8.         case 0: 
  9.       //do something. 
  10.         case 1: 
  11.             cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"]; 
  12.             if (cell == nil) 
  13.             { 
  14.                 cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"] autorelease]; 
  15.  
  16.                 //Image 
  17.                 UIImageView *p_w_picpath = [[UIImageView alloc] initWithFrame:CGRectMake(0.0f, 14.0f, 45.0f, 50.0f)]; 
  18.                 p_w_picpath.backgroundColor = [UIColor clearColor]; 
  19.                 p_w_picpath.p_w_picpath = [UIImage p_w_picpathNamed:@"folder.png"]; 
  20.                 [cell.contentView addSubview:p_w_picpath]; 
  21.                 [p_w_picpath release]; 
  22.                 //Label 
  23.                 UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(45.0f, 6.0f, 214.0f, 50.0f)]; 
  24.                 titleLabel.text = (NSString *)[(NSArray *)[self.categoryArray objectAtIndex:1] objectAtIndex:row]; 
  25.                 NSLog(@"%@ -- %d", titleLabel.text, row); 
  26.                 titleLabel.textAlignment = UITextAlignmentLeft; 
  27.                 titleLabel.numberOfLines = 3; 
  28.                 titleLabel.tag = 201; 
  29.                 titleLabel.font = [UIFont boldSystemFontOfSize:14]; 
  30.                 [cell.contentView addSubview:titleLabel]; 
  31.                 [titleLabel release]; 
  32.             } 
  33.             cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton; 
  34.             break
  35.     } 
  36.  
  37.     cell.selectionStyle = UITableViewCellSelectionStyleNone; 
  38.     return cell; 

google了一下,目前已有的解決方案是將ide

  
  
  
  
  1. cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"]; 

替換成函數

  
  
  
  
  1. cell = [tableView cellForRowAtIndexPath:indexPath]; 

大數據

  
  
  
  
  1. cell = nil;

這們作的目的去掉Cell的重用機制,可是這種方法都會在後臺隨着表格滾動一直在建立cell,經過上面源代碼中Label定義裏那句NSLog在控制檯輸出就能夠看到,雖然會自動回收內存,但確定也會給系統帶來不小開銷,因此不到萬一得以仍是不會用的。google

還有一種解決方案是本身定義Cell數組,在tableView:tableView cellForRowAtIndexPath:中進設置要顯示的cell,這是手工維護cell的一種方式,對大數據量的狀況確定是不適用的,不過也能算得上是一種思路吧,能夠參考一下。其代碼以下:spa

  
  
  
  
  1. //在構造函數裏定義cell數組 
  2. for(int i = 0; i < 31; i ++)                                                                                      
  3. {                                                                                                                 
  4.     static NSString *MyBookMarkIdentifier = @"CityMangerCell";                                                        
  5.     cityCell[i] = [[CityMangerCell alloc] initWithFrame:CGRectZero reuseIdentifier:MyBookMarkIdentifier initIndex:i]; 
  6. }                                                                                                                 
  7.  
  8. //使用它 
  9. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
  10. {                                                                                                      
  11.     if((0 <= indexPath.row) && (indexPath.row < 31))                                                       
  12.      return cityCell[indexPath.row];                                                                     
  13.     return nil;                                                                                            

後來我仔細分析了一下程序,找到了問題所在:xml

緣由是在if (cell == nil)判斷內部不該該對其label進行賦值,即不使用這句:內存

  
  
  
  
  1. titleLabel.text = (NSString *)[(NSArray *)[self.categoryArray objectAtIndex:1] objectAtIndex:row]; 

正確的作法應該是在if (cell == nil){}判斷後面進行賦值。即ci

  
  
  
  
  1. if (cell == nil)                                                                           
  2. {                                                                                          
  3.     ....                                                                                   
  4. }                                                                                          
  5. UILabel *l1 = (UILabel *)[cell.contentView viewWithTag: 201];                              
  6. l1.text = (NSString *)[(NSArray *)[self.categoryArray objectAtIndex:1] objectAtIndex:row]; 

分析緣由以下:
UITableView中被實例化的cell個數由屏高和每一個cell的高度決定,由於個人cell高度設置爲80,一屏只能 顯示6個Cell(只有6個cell被實例化),也就是隻有這6個cell纔會執行if (cell == nil){}中的代碼,從第6行日後的cell都是重用的這6個cell,也就是說從第7行開始將不會執行if (cell = nil){}中的代碼,當UITableView須要繪製第7行cell的時候,會取得第1個cell進行重用,若是咱們不把原來第1行cell中的 Label內容進行修改,那麼第7行將徹底顯示第1行中的內容,因此纔會在第6行以後開始出現數據重複的狀況。
如今我將Label內容設置的代碼放到if (cell == nil){}以後,它將會對每個被重用的cell的Label進行設定,也就不會再出現cell內容重複的現象。
但願這個問題的解決過程會對你們有所幫助。string

相關文章
相關標籤/搜索