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

如何通过配置修改自定义填充UIButton按下时的tintColor?

UIButton按下时切换tintColor的实现方案

针对你用现代UIButton.Configuration构建的按钮,以下几种方法可以实现按下状态切换tintColor的需求,优先推荐配置式或直接状态设置的方式:

方法1:直接给指定状态设置tintColor(最简方案)

UIButton本身支持给不同状态单独设置tintColor,和你设置setTitleColor的逻辑完全一致,直接加一行代码即可:

v.setTintColor(.systemBlue, for: .highlighted)

默认状态你已经设了tintColor = .systemGray,添加这行后,按钮按下时tintColor会自动切换为.systemBlue,松开后恢复默认值。

方法2:通过配置状态变体实现(现代配置式开发)

如果你想完全依托UIButton.Configuration来管理状态样式,不用直接操作按钮属性,可以创建配置的状态变体:

private lazy var toggle: UIButton = {
    let v = UIButton(type: .custom)
    
    // 构建基础配置
    var baseConfig = UIButton.Configuration.filled()
    baseConfig.titleTextAttributesTransformer = UIConfigurationTextAttributesTransformer { attrs in
        var modifiedAttrs = attrs
        modifiedAttrs.font = UIFont.monospacedSystemFont(ofSize: 12, weight: .medium)
        return modifiedAttrs
    }
    // 基础状态的前景色(对应按钮tintColor)
    baseConfig.baseForegroundColor = .systemGray
    
    // 生成高亮状态的配置变体
    var highlightedConfig = baseConfig.updated(for: .highlighted)
    highlightedConfig.baseForegroundColor = .systemBlue // 按下时的目标颜色
    
    // 绑定配置和状态变体
    v.configuration = baseConfig
    v.configuration?.updatedConfiguration(for: .highlighted) = highlightedConfig
    
    // 你的其他层样式设置
    v.layer.cornerRadius = 5
    v.layer.cornerCurve = .continuous
    v.layer.borderWidth = 1
    v.layer.borderColor = UIColor.systemYellow.cgColor
    v.clipsToBounds = true
    v.setTitle("Log", for: [])
    v.setTitleColor(.systemGray3, for: [])
    // 这里可以不用再单独设置v.tintColor,因为baseForegroundColor已经映射到tintColor
    ...
}()

这里的baseForegroundColor是配置中对应按钮tintColor的属性,通过状态变体设置后,按钮会自动在状态变化时切换颜色,完全符合你“通过配置实现”的需求。

方法3:用配置更新处理器做动态逻辑(灵活场景)

如果需要更复杂的状态判断(比如结合禁用+高亮状态),可以用configurationUpdateHandler动态调整:

private lazy var toggle: UIButton = {
    let v = UIButton(type: .custom)
    v.configuration = .filled()
    v.configuration?.titleTextAttributesTransformer = UIConfigurationTextAttributesTransformer { attrs in
        var modifiedAttrs = attrs
        modifiedAttrs.font = UIFont.monospacedSystemFont(ofSize: 12, weight: .medium)
        return modifiedAttrs
    }
    
    // 设置状态更新处理器
    v.configurationUpdateHandler = { button in
        if button.isHighlighted {
            button.tintColor = .systemBlue
        } else {
            button.tintColor = .systemGray
        }
    }
    
    // 其他样式设置
    v.layer.cornerRadius = 5
    v.layer.cornerCurve = .continuous
    v.layer.borderWidth = 1
    v.layer.borderColor = UIColor.systemYellow.cgColor
    v.clipsToBounds = true
    v.setTitle("Log", for: [])
    v.setTitleColor(.systemGray3, for: [])
    v.tintColor = .systemGray
    ...
}()

这种方式适合需要根据多个状态组合调整tintColor的场景,逻辑更灵活。

注意点

  • 如果同时用setTintColor(_:for:)和配置的baseForegroundColor,前者优先级更高,会覆盖配置的设置。
  • 所有方案都只针对tintColor(或配置中对应的前景色属性),完全不涉及backgroundColor,符合你的要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 16:15:40