Some UI elements don't acquire UIAppearance traits - ios

I am trying to use UIAppearance to get a uniform color theme in my iOS app. For example I try to set the text color of all UILabel objects as follows:
[[UILabel appearance] setTextColor:[UIColor colorWithRed:0.7 green:0.07 blue:0.12 alpha:1]];
This works fine for all objects statically defined in my storyboard/XIBs. However, sometimes I need to dynamically create a UILabel in a view. In these cases, the UIAppearance is not used. Instead the default text color (black) is used instead.
Has anyone run into this issue/ found a way around it other than resorting to the old "set every element manually" approach?

Seems that not all the classes support UIAppearance and UILabel is not one of those.
Check this question for more info:
UIAppearance not taking effect on UILabels created programatically
Here's a list of classes that support UIAppearance:
http://blog.mosheberman.com/list-of-classes-that-support-uiappearance-in-ios-5/

Related

Defining colours programmatically and using them in Interface Builder

I want to customize the colours of an App reusing the same elements but changing the colours.
These elements are simple Views, UIButton, UILabel, etc. nothing fancy. The colours may come from a XML or plist I will preload and parse to UIColor.
Yes, I can create an outlet from each of them and set them manually, but I got hundreds of elements and I want to avoid this path.
I tried IBInspectable, without luck, I’m looking for a widespread solution, all views, all VCs.
I am coding in Objective-C by the way...
Could you suggest any approach on how should I do this?
Comment if you want more detailing…
Thank you all very much!
Couple options...
Subclass your UI elements, and use MYUIButton instead of UIButton, for example, or
Look at UIAppearance proxy - https://developer.apple.com/reference/uikit/uiappearance - Using that, you can set default appearance characteristics for the whole app.
Example:
[[UIButton appearance] setBackgroundColor:[UIColor yellowColor]];
[[UILabel appearance] setBackgroundColor:[UIColor orangeColor]];
If you include those two lines (often done in AppDelegate / didFinishLaunchingWithOptions), every UIButton in your app will have a yellow background, and every UILabel will have an orange background.
(However, you will not see these changes in Interface Builder)
Edit:
As Charles mentions in his comment, you can create subclasses and then apply appearance changes to only those classes.
Suppose you have 3 button "types" that you want to apply a "color scheme" to - dark-blue, medium-blue, light-blue or dark-red, medium-red, light-red, etc. You could take the approach of creating DarkUIButton, MediumUIButton and LightUIButton subclasses. Then, when you load your color scheme...
[[DarkUIButton appearance] setBackgroundColor:scheme.darkcolor];
[[MediumUIButton appearance] setBackgroundColor:scheme.mediumcolor];
[[LightUIButton appearance] setBackgroundColor:scheme.lightcolor];

How to make the background of all UITextViews Purple without subclassing?

I have an app that I want to debug. I'd like every UITextview within the app to have a purple background.
I think method swizzling is a possible solution, but I have not been able to get this to work.
Question: How can I do this without subclassing or manually setting each textview's background color?
Thank you
Something like this should do the trick:
[[UITextView appearance] setBackgroundColor:[UIColor purpleColor]];
The appearance proxy was introduced in iOS5 as a convenient way for styling core UIKit classes without subclassing. It can be used in a variety of really useful ways such as setting a UINavigationBar's tint color, button tints, etc.

appearance proxy not working as intended for UIButton font

im currently styling my app via the appearance proxy and i ran into this problem:
when i set properties on the UIButton appearance my font is ignored:
[buttonAppearance setTitleColor:darkColor forState:UIControlStateNormal];
[buttonAppearance.titleLabel setFont:[UIFont fontWithName:#"Helvetica Neue" size:10.0]];
the first line is applied properly (darkColor is some UIColor), but my font change is ignored completely.
When i copy the line into my ViewController and apply it to a concrete button it works fine.
Am i missing something?
any help appreciated! ty
The font name is wrong, it should be HelveticaNeue, without the space between.
In the future if you want to see other iOS font names you should check this website piece of code
EDIT
After a closer look I realized that you are trying to set the appearance of the button's title which is a UILabel, sadly UILabel doesn't have the font property in the UIAppearance proxy and that's why the font doesn't work.
I have found this class TWTButton.h, who resolved my problems adding a new appearance selector [setTitleFont:] to the UIButton class.
buttonAppearance = [TWTButton appearance];
[buttonAppearance setTitleFont:[UIFont systemFontOfSize:10.0f]];
You may read more about this here : http://toastmo.com/blog/2013/01/17/uiappearance/

Changing the font of every UILabel in a large app

Here's an interesting problem for you:
We are in the process of re-skinning our entire app, which consists of over 100,000 lines of code and almost 100 XIB files. The new design requires (almost) every label in the app to use a new custom font, whereas the old app uses the default font of Helvetica Neue.
What is the most efficient way of changing as many of the UILabels as possible? We don't want to have to manually change thousands of labels both in code and in XIBs (which is especially difficult because we are using a non-system font).
We've discussed swizzling UILabel's creation methods to default to using the new custom font, which would still allow for the few labels that would remain in Helvetica Neue to be customized after creation.
Thoughts?
Take a look at NUI https://github.com/tombenner/nui.
You can customize a lot controls with it using a CSS-like stylesheet and implement it via subclasses or categories.
You should probably subclass UILabel and override either an initmethod of your choice, or awakeFromNib, and set the custom font there. Then you can go through the xib, either manually, or open it up in a text-editor and add a line like
<string key="X.CustomClassName">YourCustomLabelClass</string>
To set the specified label to your custom label class.
Swizzling is a good option . If you want to do it other way and have problems with custom fonts, I usually make a trivial subclass of UILabel that changes it's font in awakeFromNib for each custom font so I can lay them out in the interface builder.
But... This comes to my mind:
[[UILabel appearance] setFont:xxx];
I am not sure how you would deal with keeping the size, though. Perhaps swizzle is the best choice

Alternatives to appearance proxy for Table Cells' UILabel setFont

I'm loving being able to use an appearance proxy in my iOS5 app to customise the NavigationController UI elements system-wide, however:
I have a lot of nested tables in my app, of which I'd love to be able to change the font across all table cells. They are mainly statically created. I've put some cell generation inside of a class, being read from an array, but the main issue lies with a large contents section I've tabled in Interface Builder. IB doesn't seem to have the option for mass-font setting.
I was wondering if anyone could help me find a way to set all the UITableCell fonts in one go?
Perhaps something like:
[[UILabel appearance] setFont:[UIFont fontWithName:#"Times" size:17.00];
You can use appearanceWhenContainedIn: to narrow down which UIViews you'd like to set the appearance for.
In your example, try:
[[UILabel appearanceWhenContainedIn:[UITableViewCell class], nil]
setFont:[UIFont fontWithName:#"Times" size:17.00]];
Actually, no. It is not valid to use UIAppearance to style a UILabel. See my self-answered question here. It kinda works, but it's not valid, for the reasons outlined over there.

Resources