swiftuikituibutton

setting adjustsImageWhenHighlighted with UIButtonConfiguration


Since adjustsImageWhenHighlighted is deprecated in iOS 15.0, what's the way to set it with UIButtonConfiguration? If I set it directly, I get a message saying "You may customize to replicate this behavior via a configurationUpdateHandler", but what exactly should I be doing to set this in configurationUpdateHandler? Thanks


Solution

  • This is the basics...

    Assuming you have "normal" and "highlighted" images:

        // let's use new UIButton.Configuration
        newButton.configuration = .plain()
        
        newButton.configurationUpdateHandler = { button in
            var config = button.configuration
            config?.image = button.isHighlighted ? imgHighlighted : imgNormal
            button.configuration = config
        }
    

    Here's a runnable example, that uses UIGraphicsImageRenderer to create a "darkened" version of the button image "on-the-fly":

    class ViewController: UIViewController {
        
        override func viewDidLoad() {
            super.viewDidLoad()
        
            guard let imgNormal = UIImage(named: "myButtonImage")
            else {
                print("Could not load images!")
                return
            }
            
            // generate a "darkened" version of the image
            let rndr = UIGraphicsImageRenderer(size: imgNormal.size)
            let imgHighlighted = rndr.image { (ctx) in
                imgNormal.draw(at: .zero)
                UIColor.black.withAlphaComponent(0.5).setFill()
                ctx.cgContext.fill(CGRect(origin: .zero, size: imgNormal.size))
            }
            
            let oldButton = UIButton()
            let newButton = UIButton()
    
            // "standard" button
            oldButton.setImage(imgNormal, for: [])
            // default is .adjustsImageWhenHighlighted = true
            
            // let's use new UIButton.Configuration
            newButton.configuration = .plain()
            
            newButton.configurationUpdateHandler = { button in
                var config = button.configuration
                config?.image = button.isHighlighted ? imgHighlighted : imgNormal
                button.configuration = config
            }
            
            [oldButton, newButton].forEach { b in
                b.translatesAutoresizingMaskIntoConstraints = false
                view.addSubview(b)
            }
            
            let g = view.safeAreaLayoutGuide
            NSLayoutConstraint.activate([
                
                oldButton.topAnchor.constraint(equalTo: g.topAnchor, constant: 20.0),
                oldButton.widthAnchor.constraint(equalToConstant: 80.0),
                oldButton.heightAnchor.constraint(equalTo: oldButton.widthAnchor),
                oldButton.centerXAnchor.constraint(equalTo: g.centerXAnchor),
                
                newButton.topAnchor.constraint(equalTo: oldButton.bottomAnchor, constant: 20.0),
                newButton.widthAnchor.constraint(equalTo: oldButton.widthAnchor),
                newButton.heightAnchor.constraint(equalTo: oldButton.widthAnchor),
                newButton.centerXAnchor.constraint(equalTo: g.centerXAnchor),
                
            ])
            
        }
        
    }
    

    When you run this, the two buttons should look and function the same.