首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

iOS UITableView 自定義 Cell 中 TextView 內容保存導致數據重複的解決方法

     編輯:程式設計綜合問答

在 UITableView 的自定義 Cell 中包含 UITextView 時,若在 textViewDidEndEditing: 中向數據源數組重複添加對象,會導致 Cell 重複顯示、數據錯亂。

問題代碼分析

- (void)textViewDidEndEditing:(UITextView *)textView {
    FeedbackQuestionDC *feedBack = [dataArray objectAtIndex:textView.tag];
    feedBack.FeedbackQuestionDC_Answers = textView.text;
    
    [dataArray addObject:feedBack]; // 錯誤:重複添加同一對象!
    [myTableView reloadData];
}

錯誤原因

  1. feedBack 已經存在於 dataArray 中(通過 objectAtIndex: 獲取)
  2. addObject: 將同一對象再次添加到數組末尾
  3. reloadData 後,數據源包含重複對象,導致 Cell 重複
  4. 對象屬性已修改(feedBack.FeedbackQuestionDC_Answers = textView.text),無需重新添加

正確解決方法

- (void)textViewDidEndEditing:(UITextView *)textView {
    FeedbackQuestionDC *feedBack = [dataArray objectAtIndex:textView.tag];
    feedBack.FeedbackQuestionDC_Answers = textView.text;
    
    // 移除錯誤行:[dataArray addObject:feedBack];
    // 數據已在原對象中更新,直接刷新即可
    [myTableView reloadData]; 
    // 或局部刷新:[myTableView reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:textView.tag inSection:0]] withRowAnimation:UITableViewRowAnimationNone];
}

完善的 Cell 實現模式

1. Cell 標識符複用

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *identifier = @"FeedbackCell";
    FeedbackCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
    if (!cell) {
        cell = [[FeedbackCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
    }
    
    FeedbackQuestionDC *item = dataArray[indexPath.row];
    cell.configureWithItem:item indexPath:indexPath];
    cell.textView.tag = indexPath.row; // 設置 tag 識別行
    cell.textView.delegate = self;
    
    return cell;
}

2. 自定義 Cell 類別封裝配置邏輯

// FeedbackCell.h
@interface FeedbackCell : UITableViewCell
@property (weak, nonatomic) IBOutlet UITextView *textView;
@property (weak, nonatomic) IBOutlet UILabel *label;
- (void)configureWithItem:(FeedbackQuestionDC *)item indexPath:(NSIndexPath *)indexPath;
@end

// FeedbackCell.m
- (void)configureWithItem:(FeedbackQuestionDC *)item indexPath:(NSIndexPath *)indexPath {
    self.label.text = item.FeedbackQuestionDC_QuestionText;
    self.textView.text = item.FeedbackQuestionDC_Answers;
    self.textView.tag = indexPath.row;
}

關鍵最佳實踐

  • 數據源單一來源:模型對象只在數組中存在一份,修改屬性即可,勿重複添加
  • Cell 複用機制:使用 dequeueReusableCellWithIdentifier: 並正確配置
  • Tag 識別行:在 cellForRowAtIndexPath 中設置 textView.tag = indexPath.row
  • 局部刷新:使用 reloadRowsAtIndexPaths:withRowAnimation: 替代 reloadData 提升性能
  • 鍵盤處理:配合 IQKeyboardManager 或手動監聽鍵盤通知調整內容邊距

現代替代:UICollectionView + Compositional Layout

複雜表單頁面建議使用 UICollectionView 配合 UICollectionViewCompositionalLayout,支援自尺寸 Cell、更靈活的佈局與更好的性能。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved