Force View Controller to Reload to Refresh Uiappearance Changes

Does UIAppearance work outside of AppDelegate?

If you are using xib to create your view you should do the appearance customization within the AppDelegate since customization should be performed before creating any UIControl objects. You can customize it for different view controllers/ containers using appearanceWhenContainedIn

To customize the appearances for instances of a class contained within an instance of a container class, or instances in a hierarchy, use +appearanceWhenContainedIn: for the appropriate appearance proxy.

For example:

[[UIBarButtonItem appearanceWhenContainedIn:[UINavigationBar class], nil] setTintColor:myNavBarColor];   
[[UIBarButtonItem appearanceWhenContainedIn:[UINavigationBar class], [UIPopoverController class], nil] setTintColor:myPopoverNavBarColor];

Use ViewController class

 [[UIStepper appearanceWhenContainedIn:[MainViewController class], nil]setTintColor:[UIColor redColor]];
[[UIStepper appearanceWhenContainedIn:[DetailViewController class], nil]setTintColor:[UIColor greenColor]];

If you are creating the controls programmatically, no matter customize just before creating the control

 [[UIStepper appearance]setTintColor:[UIColor redColor]];
UIStepper *stepper = [[UIStepper alloc]init];
[self.view addSubview: stepper];

Reloading tab bar appearance

With iOS 13 you can override traitCollectionDidChange(_:) in UITabBarController to make changes. See documentation.


class TabBarControllerViewController: UITabBarController {


override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
self.tabBar.barTintColor =
self.tabBar.unselectedItemTintColor = UIColor.darkGray
self.tabBar.tintColor = UIColor.white

UIAppearance has no effect on Label text color

Referring to this, UIAppearance kind of doesn't really seem work with UILabel...

Since you're subclassing from UILabel, maybe it would make sense to set textcolor property initWithFrame: method on in your MessageLabel class?

Or another option, since you say these MessageLabel instances are used for UITableViewCell's background, maybe it would make sense to leave label's background clear and change background of cell itself, for example in tableView:willDisplayCell:forRowAtIndexPath: method in tableView's delegate?

How to create a proxy protocol like UIAppearance

Just make the proxy a static object and access it through class-level methods, the same way you'd implement a singleton, e.g.

@implementation MyClass

+ (MyProxyObject *)proxy
static MyProxyObject *sharedProxy = nil;
if (sharedProxy == nil)
sharedProxy = [[MyProxyObject alloc] init];
return sharedProxy;


Then for any property of your class, e.g. textColor, just have your class use the value in [[self class] proxy].textColor instead of storing its own value. E.g.

@interface MyClass : UIView

@property (nonatomic, strong) textColor


@implementation MyClass

- (UIColor *)textColor
return textColor ?: [[self class] proxy].textColor


If you need a way to refresh your onscreen views immediately whenever a property on the proxy is changed, you could do that by having the proxy broadcast an NSNotification in its textColor setter method, and have all the instances observe that notification and call setNeedsDisplay on themselves when they receive it.

Related Topics

Leave a reply