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

UITableViewCell选中状态下自定义accessoryView的tintColor修改问题

问题:UITableViewCell选中时自定义accessoryView图标消失,tintColor修改无效

我为UITableViewCell的accessoryView设置了自定义图标,代码如下:

let customDetailDisclosureButton = UIButton.init(type: .detailDisclosure)
customDetailDisclosureButton.setImage(UIImage(named: "custom")?.withRenderingMode(.alwaysTemplate), for: .normal)
cell.accessoryView = customDetailDisclosureButton

但当单元格被选中时,自定义图标会消失(表现为accessoryView隐藏)。我尝试在单元格选中时将accessoryView的tintColor改为白色,但并未生效,尝试代码如下:

func tableView(_: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
    
    print("Will select row at: \(indexPath)")
    let selectedCell = tableView.cellForRow(at: indexPath)
    selectedCell?.textLabel?.textColor = .white
    
    if let accessoryButton = selectedCell?.accessoryView as? UIButton {
            
        // !! Doesn't change the tint color !!
        accessoryButton.tintColor = .white
    }

    guard let selectedIndexPath = self.tableView.indexPathForSelectedRow else {
        print("No existing selected row at: \(indexPath)")
        return indexPath
    }
    
    
    // The same cell has been selected twice
    if selectedIndexPath == indexPath {
        print("Same cell selected twice: \(indexPath)")
        return indexPath
    }
        
    print("Resetting to default \(selectedIndexPath)")
    // Reset to default
    let previousSelectedCell = tableView.cellForRow(at: selectedIndexPath)
    previousSelectedCell?.textLabel?.textColor = .black
    previousSelectedCell?.accessoryView?.tintColor = .systemBlue
    
    return indexPath
}

请问如何解决选中状态下accessoryView的tintColor不生效且图标消失的问题?


解决方案

方法1:禁用按钮的自动状态图标替换

.detailDisclosure类型的UIButton在选中/高亮状态下,系统会自动替换默认图标,导致自定义图标被覆盖。需要为所有状态设置自定义图标,并关闭自动调整:

let customDetailDisclosureButton = UIButton(type: .detailDisclosure)
let customImage = UIImage(named: "custom")?.withRenderingMode(.alwaysTemplate)
// 为所有状态绑定自定义图标
customDetailDisclosureButton.setImage(customImage, for: .normal)
customDetailDisclosureButton.setImage(customImage, for: .highlighted)
customDetailDisclosureButton.setImage(customImage, for: .selected)
// 禁止按钮自动调整图标样式
customDetailDisclosureButton.adjustsImageWhenHighlighted = false
customDetailDisclosureButton.adjustsImageWhenSelected = false
cell.accessoryView = customDetailDisclosureButton

方法2:改用选中/取消选中回调处理样式

willSelectRowAt执行时单元格未真正进入选中状态,后续系统的默认样式会覆盖你的修改。改用didSelectRowAt和didDeselectRowAt回调:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    guard let cell = tableView.cellForRow(at: indexPath) else { return }
    cell.textLabel?.textColor = .white
    (cell.accessoryView as? UIButton)?.tintColor = .white
}

func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
    guard let cell = tableView.cellForRow(at: indexPath) else { return }
    cell.textLabel?.textColor = .black
    (cell.accessoryView as? UIButton)?.tintColor = .systemBlue
}

方法3:自定义Cell重写状态方法

创建自定义UITableViewCell,重写选中/高亮状态的处理逻辑,完全控制样式:

class CustomCell: UITableViewCell {
    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
        textLabel?.textColor = selected ? .white : .black
        (accessoryView as? UIButton)?.tintColor = selected ? .white : .systemBlue
    }
    
    override func setHighlighted(_ highlighted: Bool, animated: Bool) {
        super.setHighlighted(highlighted, animated: animated)
        textLabel?.textColor = highlighted ? .white : .black
        (accessoryView as? UIButton)?.tintColor = highlighted ? .white : .systemBlue
    }
}

使用时注册该自定义Cell,在cellForRowAt中初始化并设置accessoryView即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 22:28:31