如何解决UITableView单元格内签名视图重复显示问题
解决UITableView单元格复用导致签名视图重复的问题
问题核心
你的问题根源在于错误复用了签名视图实例,而非在单元格复用时正确重置/恢复签名数据。当前代码直接将SamsoSignatureView实例存入数组并复用,导致滚动时同一个视图被多个单元格引用,最终出现签名串位的情况。
正确解决方案
核心思路:不存储签名视图实例,只存储每个行对应的签名数据(如pathArray),单元格复用时根据数据重置视图内容,而非替换视图本身。
1. 修改数据模型
只保留签名数据,移除视图实例的存储:
struct SignatureData { let row: Int var pathArray: NSMutableArray? }
2. 重写单元格的prepareForReuse
在ProfileSignataureTableViewCell中添加该方法,确保复用前清空旧签名:
class ProfileSignataureTableViewCell: UITableViewCell { // 你的其他控件定义 override func prepareForReuse() { super.prepareForReuse() // 重置签名视图状态 signatureView?.pathArray = NSMutableArray() // 如果签名视图有自带的清空方法,也可直接调用: // signatureView?.clearSignature() } }
3. 修正cellForRowAt逻辑
不再存储视图实例,改为根据数据恢复签名内容:
// 全局存储签名数据的数组 var signatureDataArray: [SignatureData] = [] func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cellReusableId = String(describing: ProfileSignataureTableViewCell.self) guard let cell = tableView.dequeueReusableCell(withIdentifier: cellReusableId, for: indexPath) as? ProfileSignataureTableViewCell else { fatalError("Cell not exists in storyboard") } // 设置控件代理与tag cell.firstNameText.delegate = self cell.lastNameText.delegate = self cell.ageText.delegate = self cell.firstNameText.tag = indexPath.row cell.lastNameText.tag = indexPath.row cell.ageText.tag = indexPath.row cell.signatureView?.delegate = self cell.signatureView?.tag = indexPath.row // 恢复当前行的签名数据 if let existingData = signatureDataArray.first(where: { $0.row == indexPath.row }) { cell.signatureView?.pathArray = existingData.pathArray ?? NSMutableArray() } else { // 无数据则清空(prepareForReuse已处理,此处做双重保障) cell.signatureView?.pathArray = NSMutableArray() } // 绑定清空按钮 cell.btn_clear.tag = indexPath.row cell.btn_clear.addTarget(self, action: #selector(editButtonPressed), for: .touchUpInside) return cell }
4. 保存签名数据
在签名完成的代理方法中(根据你的SamsoSignatureView实际代理调整)更新数据:
// 示例代理方法,以你的实际回调为准 func signatureViewDidFinishSigning(_ signatureView: SamsoSignatureView) { let row = signatureView.tag // 更新已有数据或新增数据 if let index = signatureDataArray.firstIndex(where: { $0.row == row }) { signatureDataArray[index].pathArray = signatureView.pathArray } else { signatureDataArray.append(SignatureData(row: row, pathArray: signatureView.pathArray)) } }
5. 处理清空按钮逻辑
@objc func editButtonPressed(sender: UIButton) { let row = sender.tag // 删除对应行的签名数据 if let index = signatureDataArray.firstIndex(where: { $0.row == row }) { signatureDataArray.remove(at: index) } // 刷新对应行,确保视图更新 tableView.reloadRows(at: [IndexPath(row: row, section: 0)], with: .automatic) }
原方案失效原因
- 直接存储
SamsoSignatureView实例,导致同一个视图被多个单元格引用,滚动时视图在不同单元格间迁移,造成签名串位。 - 即使尝试恢复
pathArray,视图实例的复用会导致绘制状态混乱,因为视图本身是同一个对象,不同单元格的显示会互相影响。
内容的提问来源于stack exchange,提问作者vladislav.samsotech
相关产品推荐
相关产品推荐

