iOS UITableView设置Destructive删除按钮时背景闪白问题求助
这个问题我之前做项目时也踩过坑,其实根源是UIKit对UITableViewRowActionStyleDestructive样式的默认行为设计:
当你使用Destructive样式的行操作按钮时,系统会默认给对应的单元格添加一个高亮过渡动画——在用户点击按钮的瞬间,它会临时把单元格的backgroundColor切换为白色(或系统默认的高亮色),然后再恢复原状。如果你的单元格用了自定义背景色、背景视图或者圆角样式,这个临时的颜色切换就会被用户明显察觉到,表现为你看到的“闪白”。而UITableViewRowActionStyleNormal样式没有这个默认的高亮动画逻辑,所以Edit按钮不会出现这个问题。
下面给你两个实用的解决思路:
1. 重写自定义Cell的高亮方法(兼容iOS 10及以下)
如果你的项目需要兼容iOS 10或更早版本,必须使用UITableViewRowAction,可以在自定义UITableViewCell中重写setHighlighted:animated:方法,阻止系统修改单元格背景色:
Objective-C代码:
- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated { // 先保存当前的背景色 UIColor *originalBgColor = self.backgroundColor; // 调用父类方法执行其他高亮逻辑 [super setHighlighted:highlighted animated:animated]; // 恢复原来的背景色,覆盖系统的默认高亮色 self.backgroundColor = originalBgColor; }
Swift代码:
override func setHighlighted(_ highlighted: Bool, animated: Bool) { let originalBgColor = backgroundColor super.setHighlighted(highlighted, animated: animated) backgroundColor = originalBgColor }
另外也可以尝试把单元格的selectionStyle设为.none,但这个会同时禁用单元格正常选中时的高亮效果,所以重写高亮方法是更灵活的方案。
2. 改用UIContextualAction(iOS 11+推荐)
从iOS 11开始,苹果推出了UIContextualAction来替代旧的UITableViewRowAction,它的自定义性更强,也没有默认的单元格闪白问题。你可以用它来创建滑动操作按钮:
Swift代码示例:
override func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? { // 创建Delete操作 let deleteAction = UIContextualAction(style: .destructive, title: "Delete") { [weak self] (action, view, completionHandler) in // 在这里执行你的删除逻辑 self?.yourDataSourceArray.remove(at: indexPath.row) self?.tableView.deleteRows(at: [indexPath], with: .automatic) // 告诉系统操作完成 completionHandler(true) } deleteAction.backgroundColor = .systemRed // 自定义按钮背景色 // 创建Edit操作 let editAction = UIContextualAction(style: .normal, title: "Edit") { (action, view, completionHandler) in // 执行你的编辑逻辑 completionHandler(true) } editAction.backgroundColor = .systemBlue // 返回配置好的滑动操作 return UISwipeActionsConfiguration(actions: [deleteAction, editAction]) }
这个API不仅解决了闪白问题,还支持设置按钮图标、调整圆角等更丰富的自定义效果,是现在的首选方案。
内容的提问来源于stack exchange,提问作者Supertecnoboff

