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

RXSwift结合UITableView如何根据Observable值动态切换行侧滑操作

实现思路

UITableView的trailingSwipeActionsConfigurationForRowAt代理方法需要同步返回侧滑配置,因此我们需要先持有当前最新的商品列表数据,直接读取对应行的isEnabled属性判断要展示的侧滑按钮。

步骤1:维护本地最新商品列表

因为你的interactionService.products是Observable类型,我们需要订阅它的更新,把最新值存在本地变量中,方便同步读取:

// ViewController 新增属性
private var currentProducts: [Product] = []
private let disposeBag = DisposeBag()

// 在viewDidLoad中添加订阅逻辑
override func viewDidLoad() {
    super.viewDidLoad()
    // 其他初始化逻辑...
    
    // 订阅商品列表更新,同步到本地变量
    self.interactionService.products
        .subscribe(onNext: { [weak self] products in
            guard let self = self else { return }
            self.currentProducts = products
            self.tableView.reloadData() // 刷新列表更新侧滑状态
        })
        .disposed(by: self.disposeBag)
}

步骤2:修改侧滑代理方法

新增inStockAction逻辑,根据当前商品的isEnabled属性切换要返回的侧滑配置:

func tableView(
    _ tableView: UITableView,
    trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath
) -> UISwipeActionsConfiguration? {
    // 安全校验行索引是否合法
    guard indexPath.row < currentProducts.count else { return nil }
    let currentProduct = currentProducts[indexPath.row]
    
    // 1. 定义Sold Out操作
    let soldOutAction = UIContextualAction(
        style: .normal,
        title: "Sold Out"
    ) { [weak self] (_, _, completionHandler) in
        guard let self = self else { return }
        self.interactionService.products
            .map({ $0[indexPath.row] })
            .take(1)
            .do(onNext: { [weak self] product in
                self?.analytics.userMarkedAsSoldOut(product: product.productID)
            })
            .flatMapLatest({ self.interactionService.disableProduct($0) })
            .subscribe(onCompleted: {
                completionHandler(true)
            })
            .disposed(by: self.disposeBag)
    }
    soldOutAction.backgroundColor = UIColor(red: 0.996, green: 0.09, blue: 0.478, alpha: 1)
    
    // 2. 新增In Stock操作
    let inStockAction = UIContextualAction(
        style: .normal,
        title: "In Stock"
    ) { [weak self] (_, _, completionHandler) in
        guard let self = self else { return }
        self.interactionService.products
            .map({ $0[indexPath.row] })
            .take(1)
            .do(onNext: { [weak self] product in
                // 对应上报标记为在售的事件,可根据实际需求修改
                self?.analytics.userMarkedAsInStock(product: product.productID)
            })
            .flatMapLatest({ self.interactionService.enableProduct($0) })
            .subscribe(onCompleted: {
                completionHandler(true)
            })
            .disposed(by: self.disposeBag)
    }
    inStockAction.backgroundColor = UIColor(red: 0.204, green: 0.78, blue: 0.349, alpha: 1) // 示例绿色,可自定义
    
    // 3. 根据isEnabled判断要返回的操作
    let actions: [UIContextualAction]
    if currentProduct.isEnabled {
        actions = [soldOutAction]
    } else {
        actions = [inStockAction]
    }
    
    let config = UISwipeActionsConfiguration(actions: actions)
    config.performsFirstActionWithFullSwipe = false
    return config
}

补充说明

如果你的interactionService.products本身是BehaviorRelay/BehaviorSubject类型,已经存储了当前最新值,也可以直接读取它的value属性判断,不需要额外维护currentProducts变量。


内容的提问来源于stack exchange,提问作者Mike Simz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 12:39:04