borderColor of a UIButton doesn't respect overrideUserInterfaceStyle

352 views Asked by At

I ran into an issue I'm having trouble explaining. I have a simple UIButton for which I set the following properties:

class SecondaryButton: AppButton {
    override func awakeFromNib() {
        super.awakeFromNib()        
        cornerRadius = frame.height / 2
        borderWidth = 2
        borderColor = .formedText.withAlphaComponent(0.2)
    }
}

.formedText access a namedColor that is supposed to be black in light mode and white in dark mode (I am not using .label because that isn't pure white or pure black on macOS Catalyst).

static let formedText = UIColor(named: "Formed Text")

This button is used in a page where I tried overriding the userInterfaceStyle in several places by calling overrideUserInterfaceStyle = .light

  • on the entire window
  • on the view controller
  • on the button itself

So here's the question: As you can see the button has a white border, even though the named colour is supposed to be black when userInterfaceStyle is light. If I set the exact same colour as the background of the same button by calling backgroundColor = .formedText.withAlphaComponent(0.2) it works just fine (i.e. the background is black with alpha 0.2).

Setting the color to something not affected by dark mode (such as .black or .red) works fine.

What am I missing here?

Please let me know if any further details are needed, and thanks in advance for any hints.

THis is the named color enter image description here

2

There are 2 answers

0
Mojtaba Hosseini On BEST ANSWER

borderColor is a cgColor which is not adaptive.

You can handle the appearance change and update the border color inside the traitCollectionDidChange function:

override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
    super.traitCollectionDidChange(previousTraitCollection)
    
    if traitCollection.hasDifferentColorAppearance(comparedTo: previousTraitCollection) {
        // Set the color again here if needed 
    }
}

More information here

0
Ahmadreza On

I use this extension for border colors:

extension UIColor {
    
    static func getUpdatedColor(for colorName: String)-> UIColor {
        return UIColor(named: colorName, in: .main, compatibleWith: .current)!.resolvedColor(with: .current)
    }
}