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

TableView行内按钮单选功能实现求助:选中按钮时取消其他选中并设置红色背景

解决TableView行内按钮单选并切换背景色的问题

我来帮你搞定这个按钮单选的需求~你的代码目前已经实现了按钮的创建和点击后的业务逻辑,但缺少单选状态管理和背景色切换的核心部分,下面是具体的修改方案:

第一步:添加按钮数组统一管理所有按钮

首先在你的类里新增一个数组属性,用来保存所有创建的单位按钮,这样后续可以方便地遍历和修改它们的状态:

// 用来保存所有单位按钮,方便统一管理选中状态
private var unitButtons: [UIButton] = []

第二步:修改按钮创建方法,将按钮加入管理数组

在createUnits方法里,把创建好的按钮添加到上面的数组中:

func createUnits(_ model : UnitAndColors, tag: Int) -> UIStackView {
    let stackViewMain = UIStackView()
    stackViewMain.axis = .horizontal
    stackViewMain.spacing = 4
    let labelPackingUnit = UIButton()
    labelPackingUnit.backgroundColor = Colors().colorWhite
    labelPackingUnit.tag = tag
    labelPackingUnit.setTitleColor(Colors().colorRed, for: .normal)
    // 可选:设置选中时的文字颜色,比如改为白色适配红色背景
    labelPackingUnit.setTitleColor(.white, for: .selected)
    labelPackingUnit.addTarget(self, action: #selector(selectButton(_:)), for: .touchUpInside)
    labelPackingUnit.titleLabel?.font = UIFont.fontBold16
    labelPackingUnit.contentHorizontalAlignment = .center
    labelPackingUnit.setBorder(width: 1, color: Colors().colorRed)
    labelPackingUnit.setCornerRound(value: 20.0)
    labelPackingUnit.setTitle(model.unitDesc, for: .normal)
    stackViewMain.addArrangedSubview(labelPackingUnit)
    labelPackingUnit.snp.makeConstraints { $0.size.equalTo(40) }
    
    // 将按钮加入管理数组
    self.unitButtons.append(labelPackingUnit)
    
    return stackViewMain
}

第三步:在configure方法中清空旧按钮数组

每次重新配置按钮时,需要清空之前的按钮数组,避免残留旧按钮的状态:

func configure(_ modelArray : [UnitAndColors], colorTitle:String, packingTitle:String) {
    self.unitStackView.removeAllArrangedSubviews()
    self.arrayUnitsAndColor?.removeAll()
    self.arrayUnitsAndColor = modelArray
    // 清空旧的按钮数组
    self.unitButtons.removeAll()
    let filteredArray = self.arrayUnitsAndColor?.unique { $0.colorDesc }
    var i : Int = 0
    filteredArray?.forEach { units in
        let vw = self.createUnits(units, tag: i)
        self.unitStackView.addArrangedSubview(vw)
        vw.snp.makeConstraints { $0.size.equalTo(40.0) }
        i = i + 1
    }
}

第四步:修改点击事件,实现单选和背景色切换

在selectButton方法里,先重置所有按钮的未选中状态,再设置当前点击按钮的选中样式,最后保留原有的业务逻辑:

@objc private func selectButton(_ sender : UIButton) {
    // 1. 重置所有按钮的未选中状态:背景色改回白色,边框保持红色
    unitButtons.forEach { button in
        button.backgroundColor = Colors().colorWhite
        button.setBorder(width: 1, color: Colors().colorRed)
        button.isSelected = false
    }
    
    // 2. 设置当前点击按钮的选中状态:背景色改为红色
    sender.backgroundColor = Colors().colorRed
    // 可选:把选中按钮的边框改为深色,增强区分度
    // sender.setBorder(width: 1, color: .darkGray)
    sender.isSelected = true
    
    // 3. 保留你原来的业务逻辑
    let tag : Int = sender.tag
    guard let model : UnitAndColors = self.arrayUnitsAndColor?.filter({ $0.colorDesc == selectedColorName })[tag] else { return }
    selectedUnit = model.unitDesc ?? ""
    delegate?.changePrice(selectedPrice: model.modelPrice, arrayUnitsAndColor ?? [])
}

第五步:处理TableViewCell复用(如果是在Cell中实现)

如果这段代码是在TableView的Cell里,记得在prepareForReuse方法中重置按钮状态,避免复用Cell时出现状态错乱:

override func prepareForReuse() {
    super.prepareForReuse()
    // 重置所有按钮状态
    unitButtons.forEach {
        $0.backgroundColor = Colors().colorWhite
        $0.setBorder(width: 1, color: Colors().colorRed)
        $0.isSelected = false
    }
    unitButtons.removeAll()
    // 重置选中的单位
    selectedUnit = nil
}

这样修改后,点击任意按钮都会自动取消其他按钮的选中状态,同时把当前按钮的背景色改为红色,完美实现你想要的功能~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 06:55:21