Swift动态表单下UITableView滚动时UITextView文本复用问题如何解决
动态表单UITableView滚动时UITextView文本复用错乱解决方案
问题描述
你开发了包含button、textfield、textview等多种组件的动态表单,表单通过xib文件实现。目前已解决button和textfield的滚动复用问题,但始终无法处理UITableView滚动时UITextView出现的文本复用替换问题。
解决步骤
- 第一步:Cell重用前主动清空旧状态
在自定义Cell的prepareForReuse生命周期方法中,主动清空UITextView的残留文本和代理绑定,从源头避免旧内容带入新的渲染流程:
如果使用Objective-C,对应实现如下:override func prepareForReuse() { super.prepareForReuse() // 清空旧文本 customTextView.text = "" // 清空旧代理,避免错误回调 customTextView.delegate = nil }- (void)prepareForReuse { [super prepareForReuse]; self.customTextView.text = @""; self.customTextView.delegate = nil; } - 第二步:维护独立的表单数据源存储
不要依赖Cell自身存储输入内容,单独用数组/字典/表单项模型数组存储每个位置的输入值,和indexPath一一对应:// 示例:用字符串数组存储所有表单项的输入内容,初始化时和表单数量对齐 var formInputValues: [String] = Array(repeating: "", count: 表单总数量) - 第三步:cellForRow渲染时严格绑定数据源
每次配置Cell的时候,直接从数据源取对应位置的文本赋值给UITextView,不要依赖Cell的残留状态:func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "TextViewCellID", for: indexPath) as! CustomFormCell // 从数据源取对应值赋值 cell.customTextView.text = formInputValues[indexPath.row] // 绑定当前Cell对应的indexPath,方便后续输入回写 cell.bindIndexPath = indexPath // 设置代理 cell.customTextView.delegate = self return cell } - 第四步:实时监听文本变化回写数据源
实现UITextViewDelegate的textViewDidChange方法,用户输入时实时把内容同步到数据源对应位置,保证数据源和输入内容始终一致:func textViewDidChange(_ textView: UITextView) { // 通过响应链或者绑定的indexPath定位当前输入的行 guard let currentCell = textView.superview?.superview as? CustomFormCell, let currentIndex = currentCell.bindIndexPath else { return } formInputValues[currentIndex.row] = textView.text ?? "" } - 第五步:XIB配置优化
用XIB实现Cell时,不要给UITextView设置默认文本或者默认占位符,占位符逻辑请通过代码和数据源绑定实现,避免XIB默认内容导致复用错乱。
补充提示:如果需要实现UITextView的占位符效果,不要直接在XIB里加固定UILabel,建议通过
textViewDidChange判断数据源内容是否为空,动态切换文本颜色和占位显示,和数据源状态完全绑定,避免复用残留。
内容的提问来源于stack exchange,提问作者Sushil Dhital
相关产品推荐
相关产品推荐

