Lukas Lukas - 1 year ago 44
iOS Question

How can I check if an appearance property has been set?

Is there a way to check if a property has been set on an UIAppearance proxy or not?

Let's say I want to do something like:

self.lineWidth = appearance.lineWidth ? : kDefaultLineWidth;

This will not work correctly if the lineWidth was set to zero on the proxy since it would be indistinguishable from not having been set at all (assuming it's a CGFloat).

Answer Source

You shouldn't need to make that check; the appearance system will take care of it for you. In your initialiser, set lineWidth to your default value using direct ivar access instead of its setter:

_lineWidth = kDefaultLineWidth;

If an appearance property has been set for lineWidth, this will be overridden. If not, it will not be overridden.

The problem arises when you instead set lineWidth via its setter. The appearance system will then mark that instance as having been customised, and won't override your change.


One gotcha is that UIAppearance swizzles all setters that have a default apperance, and tracks when they get changed, so that UIAppearance doesn’t override your customizations. [If] we use setters in the initializer, ...for UIAppearance it now looks as though we already customized the class ourselves. Lesson: Only use direct ivar access in the initializer for properties that comply to UI_APPEARANCE_SELECTOR.