iosswiftuibutton

How to disable title color change when highlighted state for UIButton using UIButtonConfiguration is active?


This is how my UIButton is defined and initialized:

lazy var addButton: UIButton = {
    let button = UIButton(radius: 32, title: "+", font: .poppinsRegular.withSize(40), backgroundColor: .purple)
    button.menu = UIMenu(title: "")
    button.showsMenuAsPrimaryAction = true
    return button
}()


extension UIButton {
    convenience init(
        radius: CGFloat = 0,
        title: String? = nil,
        backgroundColor: UIColor? = nil,
        foregroundColor: UIColor = .white,
        font: UIFont? = nil
    ) {
        var configuration = UIButton.Configuration.filled()
        configuration.baseForegroundColor = foregroundColor
        configuration.title = title
        configuration.background.cornerRadius = radius
        configuration.cornerStyle = .fixed
        configuration.contentInsets = .zero
        configuration.titleTextAttributesTransformer = UIConfigurationTextAttributesTransformer { incoming in
            var outgoing = incoming
            outgoing.font = font
            return outgoing
        }
        configuration.baseBackgroundColor = backgroundColor
        configuration.background.backgroundColor = backgroundColor
        self.init(configuration: configuration)
    }
}

enter image description here

enter image description here

What to change to keep my title full white even when highlighted?


Solution

  • Give this a try...

    In your .titleTextAttributesTransformer:

        configuration.titleTextAttributesTransformer = UIConfigurationTextAttributesTransformer { incoming in
            var outgoing = incoming
            outgoing.font = font
            
            // add this line
            outgoing.foregroundColor = foregroundColor
            
            return outgoing
        }
    

    and add a ConfigurationUpdateHandler:

    let handler: UIButton.ConfigurationUpdateHandler = { button in
        var background = UIButton.Configuration.plain().background
        background.cornerRadius = 32
        background.backgroundColor = .purple
        button.configuration?.background = background
    }
        
    addButton.configurationUpdateHandler = handler
        
    

    Edit

    Another (better, I think) approach...

    Implement .backgroundColorTransformer in your convenience init:

    extension UIButton {
        convenience init(
            radius: CGFloat = 0,
            title: String? = nil,
            backgroundColor: UIColor? = nil,
            foregroundColor: UIColor = .white,
            font: UIFont? = nil
        ) {
            // use plain instead of filled
            var configuration = UIButton.Configuration.plain()
            configuration.baseForegroundColor = foregroundColor
            configuration.title = title
            configuration.background.cornerRadius = radius
            configuration.cornerStyle = .fixed
            configuration.contentInsets = .zero
    
            configuration.titleTextAttributesTransformer = UIConfigurationTextAttributesTransformer { incoming in
                var outgoing = incoming
                outgoing.font = font
                
                // add this line
                outgoing.foregroundColor = foregroundColor
                
                return outgoing
            }
    
            configuration.background.backgroundColor = backgroundColor
            
            // prevent default background color/tint change
            configuration.background.backgroundColorTransformer = UIConfigurationColorTransformer { _ in
                return backgroundColor!
            }
    
            self.init(configuration: configuration)
        }
    }
    

    Now, we no longer need to assign a ConfigurationUpdateHandler.