使用UIButton.Configuration导致按钮图片颜色淡入动画问题求助
我之前用自定义UIButton实现了类似分段控件的可切换按钮,切换图片颜色时原本没有动画。改用UIButton.Configuration后,按钮UI行为出现变化——只有在isHighlighted切换为false且isSelected切换为true时,图片颜色会出现淡入动画,其他状态切换都正常。求问如何去除这个动画?
旧实现代码(无动画)
class MyOldButton: UIButton { override init(frame: CGRect) { fatalError() } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) setupUI() } private var customColor: UIColor { switch (isSelected, isHighlighted) { case (true, false): return .red case (true, true): return .green case (false, false): return .blue case (false, true): return .yellow } } private func setupUI() { clipsToBounds = true adjustsImageWhenHighlighted = false adjustsImageWhenDisabled = false tintAdjustmentMode = .normal tintColor = customColor } override var isSelected: Bool { didSet { tintColor = customColor } } override var isHighlighted: Bool { didSet { tintColor = customColor } } }
新实现代码(出现异常动画)
class MyNewButton: UIButton { override init(frame: CGRect) { fatalError() } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) setupUI() } private var customColor: UIColor { switch (isSelected, isHighlighted) { case (true, false): return .red case (true, true): return .green case (false, false): return .blue case (false, true): return .yellow } } private func setupUI() { clipsToBounds = true tintAdjustmentMode = .normal backgroundColor = .clear changesSelectionAsPrimaryAction = true var config = UIButton.Configuration.filled() config.imagePlacement = .top configuration = config configurationUpdateHandler = { [weak self] button in guard let self else { return } var config = button.configuration config?.baseForegroundColor = self.customColor button.configuration = config } } }
解决方案
方法一:禁用Configuration的全局动画
在初始化按钮配置时,直接将animation属性设置为.none,从根源取消所有基于Configuration的UI更新动画:
private func setupUI() { clipsToBounds = true tintAdjustmentMode = .normal backgroundColor = .clear changesSelectionAsPrimaryAction = true var config = UIButton.Configuration.filled() config.imagePlacement = .top config.animation = .none // 关键:禁用配置更新动画 configuration = config configurationUpdateHandler = { [weak self] button in guard let self else { return } var config = button.configuration config?.baseForegroundColor = self.customColor button.configuration = config } }
方法二:在更新配置时临时禁用动画
如果只想针对特定状态更新取消动画,用UIView.performWithoutAnimation包裹配置更新代码,确保本次UI变更无动画:
configurationUpdateHandler = { [weak self] button in guard let self else { return } UIView.performWithoutAnimation { var config = button.configuration config?.baseForegroundColor = self.customColor button.configuration = config button.layoutIfNeeded() // 强制立即刷新布局 } }
两种方法都能解决异常淡入动画问题,推荐方法一,更贴合你需要的无动画状态切换需求。
内容的提问来源于stack exchange,提问作者Jon Cox
相关产品推荐
相关产品推荐

