Avoiding recursion when setting a property

I am building an app for iOS 11-13+ and am trying to implement dark mode. Since the new dynamic colors don't exist pre-13, I am using

if #available(iOS 13, *) {
    ...
} else {
    ...
}

blocks in the code.

Now I have the following problem:

@IBDesignable dynamic public var fooColor : UIColor = .gray {
    didSet {
        updateFoo()
    }
}

When the appropriate storyboard scene is initialized, the property is set with the default color. BUT, what I want to happen is to test the new color to see if it is .gray (the default color) [which I know how to do] and IF it is the default color AND we're running on iOS 13+, THEN replace the default color with some dynamic color (like, for example, .systemGray).

In other words, what I'm trying to implement is something that works like

@IBDesignable dynamic public var fooColor : UIColor = .systemGray {
    didSet {
        updateFoo()
    }
}

but which will actually compile when the target SDK is < 13.0.

How do I do this without creating an infinite recursion (be setting a new value to the property within EITHER the property's setter or it's didSet?

What is the best practice in this situation?

Thanks

This is how I'd do it:

extension UIColor {
    static let myGray: UIColor = {
        if #available(iOS 13, *) { 
            return UIColor.systemGray
        } else {
            return UIColor.gray
        }
    }()
}
@IBDesignable dynamic public var fooColor : UIColor = .myGray

Michel,

Thank you very much for your suggestion. It is an excellent suggestion, and one I (obviously) hadn’t thought of. I very much appreciate your quick and on-point response.

Cheers,

Rick Aurbach

Terms of Service

Privacy Policy

Cookie Policy