3
votes

I'm using UIAppearance to customize all UIBarButtonItem, with:

[[UIBarButtonItem appearance] setTintColor:[UIColor purpleColor]];

Apart from the poor color choice, it works great.

Now, I want some buttons with a specific style. So I create a new class, let's call it YellowDoneBarButtonItem.
I want to customize it too, so I add:

[[YellowDoneBarButtonItem appearance] setTintColor:[UIColor yellowColor]];

Unfortunately, the last call to ... appearance] setTintColor: wins, and all buttons, subclass or not, adopt the last specified color.

I can't use appearanceWhenContainedIn: because sometimes, I might have the two different button styles in the same navigation bar.

Is there a way to use UIAppearance more selectively than an all or nothing?

The doc says:

In any given view hierarchy, the outermost appearance proxy wins. Specificity (depth of the chain) is the tie-breaker. In other words, the containment statement in appearanceWhenContainedIn: is treated as a partial ordering. Given a concrete ordering (actual subview hierarchy), UIKit selects the partial ordering that is the first unique match when reading the actual hierarchy from the window down.

Any trick to bend this fact to what's needed here?

1
it appears that the actual buttons instantiated are UINavigationButton, which is a (private) subclass of UIButton. This might explain why the UIBarButtonItem appearance subclass is a catch-all..Henrik Hartz
Interesting. You should post it as an answer (with additional details if you have them), so I can accept your answer.Guillaume
There - added a minor additional detail to my answer :)Henrik Hartz

1 Answers

2
votes

It appears that the actual buttons instantiated are UINavigationButton, which is a (private) subclass of UIButton. This might explain why the UIBarButtonItem appearance subclass is a catch-all.

For my own part, I have been using UIButton's as custom views to get the appearance I needed. These can easily be overridden using UIAppearance in turn.