如何在UITableView左滑时为行文本添加删除线(替代删除)
解决UITableView左滑添加删除线(而非删除行)的问题
我来帮你搞定这个需求!你当前的代码是左滑后直接删除行,但你想要的是给行内文本加删除线(标记为完成),而不是删除数据。咱们一步步调整代码就能实现目标:
核心问题分析
你现在用了.destructive风格的UIContextualAction,而且回调里直接删除了数据和行,这就是左滑后行消失的原因。要实现你要的效果,核心是修改数据的完成状态,而非删除数据,再让单元格根据状态渲染删除线样式。
具体修改步骤
- 调整滑动操作的样式与逻辑:把操作风格从破坏性改成普通样式,自定义颜色区分完成操作,回调里标记数据为已完成而非删除。
- 给数据模型加完成状态:如果你的Core Data实体还没有
isCompleted布尔属性,需要先添加这个属性(用来标记行是否已完成)。 - 更新单元格渲染逻辑:在单元格配置方法里,根据
isCompleted状态给文本添加删除线。
修改后的完整代码示例
1. 重写滑动操作相关方法
override func tableView(_ tableView: UITableView, leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? { let complete = completeAction(at: indexPath) return UISwipeActionsConfiguration(actions: [complete]) } func completeAction(at indexPath: IndexPath) -> UIContextualAction { let action = UIContextualAction(style: .normal, title: "Complete") { [weak self] (action, view, completion) in guard let self = self else { completion(false) return } // 获取当前行对应的数据对象 let targetItem = self.fetchResultsController.object(at: indexPath) // 标记为已完成 targetItem.isCompleted = true // 保存Core Data修改 if let context = (UIApplication.shared.delegate as? AppDelegate)?.coreDataStack.persistentContainer.viewContext { do { try context.save() // 刷新该行,让删除线样式生效 self.tableView.reloadRows(at: [indexPath], with: .fade) completion(true) } catch { print(error.localizedDescription) completion(false) } } } // 给完成操作设置绿色背景,更符合语义 action.backgroundColor = .systemGreen return action }
2. 配置单元格的文本样式
在tableView(_:cellForRowAt:)方法里添加删除线渲染逻辑:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "YourCellID", for: indexPath) let item = fetchResultsController.object(at: indexPath) // 基础文本设置 let itemTitle = item.title ?? "" cell.textLabel?.text = itemTitle // 根据完成状态添加删除线 if item.isCompleted { let attributedText = NSMutableAttributedString(string: itemTitle) attributedText.addAttribute( NSAttributedString.Key.strikethroughStyle, value: NSUnderlineStyle.single.rawValue, range: NSRange(location: 0, length: attributedText.length) ) cell.textLabel?.attributedText = attributedText } else { // 未完成时清除样式,显示普通文本 cell.textLabel?.attributedText = nil cell.textLabel?.text = itemTitle } return cell }
额外提示
- 如果你的Core Data模型还没有
isCompleted属性,需要打开.xcdatamodeld文件,给对应实体添加一个Boolean类型的属性,再重新生成模型类。 - 闭包里用
[weak self]是为了避免循环引用,这是Swift开发的最佳实践。 - 用
reloadRows而不是deleteRows,才能让单元格重新渲染并显示删除线。
内容的提问来源于stack exchange,提问作者Over
相关产品推荐
相关产品推荐

