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

使用UIButton.Configuration导致按钮图片颜色淡入动画问题求助

问题: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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 06:35:16