You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS:如何单独禁用UITableViewCell的单侧滑动操作而非整体编辑?

解决方案:单独禁用UITableView某一侧的滑行动作

当然可以实现你要的效果!canEditRowAt确实是控制整行是否允许编辑(包括所有方向的滑行动作),没法单独针对某一侧做限制。不过我们可以通过动态生成滑动操作配置的方式,根据每行的当前状态来决定是否返回对应侧的滑行动作,从而实现单侧禁用的需求。

核心思路

  1. 给你的数据模型添加一个状态标记(比如isDisabled),用来记录该行当前是“已禁用”还是“正常启用”状态;
  2. 在leadingSwipeActionsConfigurationForRowAt和trailingSwipeActionsConfigurationForRowAt方法中,根据当前行的状态动态返回对应的滑动配置:
    • 当行处于已禁用状态时:只允许leading侧的“取消禁用”动作,trailing侧返回空配置(禁用该侧滑动);
    • 当行处于正常启用状态时:只允许trailing侧的“禁用”动作,leading侧返回空配置(禁用该侧滑动);
  3. 点击滑动动作后,更新对应行的状态标记,刷新该行以触发配置重新生成。

代码示例

假设你的数据模型是这样的:

struct YourModel {
    var content: String
    var isDisabled: Bool // 标记该行是否被禁用
}

然后在你的UITableViewDelegate实现中:

// 处理leading侧滑动(取消禁用)
override func tableView(_ tableView: UITableView, leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
    let model = yourDataSource[indexPath.row]
    // 如果当前行未被禁用,直接返回空配置(禁用leading侧滑动)
    guard model.isDisabled else {
        return UISwipeActionsConfiguration(actions: [])
    }
    
    // 创建“取消禁用”动作
    let enableAction = UIContextualAction(style: .normal, title: "取消禁用") { [weak self] (action, view, completionHandler) in
        // 更新模型状态
        self?.yourDataSource[indexPath.row].isDisabled = false
        // 刷新该行
        tableView.reloadRows(at: [indexPath], with: .automatic)
        completionHandler(true)
    }
    enableAction.backgroundColor = .systemGreen
    
    return UISwipeActionsConfiguration(actions: [enableAction])
}

// 处理trailing侧滑动(禁用行)
override func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
    let model = yourDataSource[indexPath.row]
    // 如果当前行已被禁用,直接返回空配置(禁用trailing侧滑动)
    guard !model.isDisabled else {
        return UISwipeActionsConfiguration(actions: [])
    }
    
    // 创建“禁用”动作
    let disableAction = UIContextualAction(style: .destructive, title: "禁用") { [weak self] (action, view, completionHandler) in
        // 更新模型状态
        self?.yourDataSource[indexPath.row].isDisabled = true
        // 刷新该行
        tableView.reloadRows(at: [indexPath], with: .automatic)
        completionHandler(true)
    }
    disableAction.backgroundColor = .systemRed
    
    return UISwipeActionsConfiguration(actions: [disableAction])
}

// 注意:canEditRowAt要保持返回true,因为我们需要允许整行的编辑权限,只是动态控制某一侧的动作
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
    return true
}

原理说明

  • 当我们在某一侧的配置方法中返回UISwipeActionsConfiguration(actions: [])时,系统会认为该侧没有可执行的滑行动作,从而禁用该侧的滑动交互;
  • 通过reloadRows刷新该行后,下次滑动时系统会重新调用对应的配置方法,根据更新后的状态生成正确的滑动操作;
  • canEditRowAt返回true保证了整行处于可编辑状态,这样我们才有机会动态控制两侧的滑动动作。

这样就能完美实现你要的状态切换:点击“禁用”后,trailing侧滑动消失,leading侧出现“取消禁用”;点击“取消禁用”后则反过来。

内容的提问来源于stack exchange,提问作者Andrew P.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:05:47