1

I'm trying to use UIAppearance to create a theme for my app.

Say I want all my UILabel's texts to be orange. I wrote:

UILabel.appearance(whenContainedInInstancesOf: [UIView.self]).textColor = .orange

But I realized that:

  • This worked for every UILabel created via Interface Builder.
  • This does not work for any UILabel created programmatically. They are displayed in black by default

Any idea how I can force programmatically created instances to be orange as well?

PS: I've also tried: UILabel.appearance().textColor = .green which is not what I want but it doesn't work either.

Mick F
  • 7,312
  • 6
  • 51
  • 98

2 Answers2

0

After some searching...

Apparently, the fact that UI elements (such as labels) created in Interface Builder are affected by .appearance() settings is not really intentional, and is probably not reliable.

In fact, the documentation seems rather confusing and misleading.

To support appearance customization, a class must conform to the UIAppearanceContainer protocol and relevant accessor methods must be marked with UI_APPEARANCE_SELECTOR.

The only classes that adopt UIAppearance protocol are

  • UIBarItem
  • UIView

and the only classes that adopt UIAppearanceContainer protocol are

  • UIPopoverController
  • UIPresentationController
  • UIView
  • UIViewController

So... best bet is probably to sub-class your labels.

DonMag
  • 69,424
  • 5
  • 50
  • 86
0

A related answer can be found here : How to default UILabel Font and Size using Swift

From that link: "UIAppearance only allows you to set properties that are flagged with UI_APPEARANCE_SELECTOR in the Objective-C header file. Since UILabel has no such properties, it cannot be styled with UIAppearance"

also from: https://developer.apple.com/documentation/uikit/uiappearance

"iOS applies appearance changes when a view enters a window, it doesn’t change the appearance of a view that’s already in a window. To change the appearance of a view that’s currently in a window, remove the view from the view hierarchy and then put it back."

also from here:trouble with UIAppearance and UIButton subclassing

"The reason it's working this way is because appearance properties are applied when the view is added to a view hierarchy, and nib-defined properties are applied before the view is added to a view hierarchy."

I tried setting the appearance of labels when in instances of a new class of view controller before programatically adding that view controller to the hierarchy, but no luck.

AmandaR
  • 81
  • 3