如何通过配置修改自定义填充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
相关产品推荐
相关产品推荐

