Defining colours programmatically and using them in Interface Builder - ios

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];

Related

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.

IOS UIAppearance

I have the following issue. I have a custom UIView which background I am trying to set using UIAppearance.
[[OptionsHeader appearance] setBackgroundColor:[UIColor headBackgroundColor]];
But when I use it like this, all the views turns to black and white.
[[UIView appearance] setBackgroundColor:[UIColor headBackgroundColor]];
Works nicely, but I need it to work nicely on that specific class.
Any help is welcome.
Kind Regards,
EZFrag
You need to implement the UIAppearance protocol in your custom class, as described here. Basically, you 'need' to augment your custom class and annotate it with UI_APPEARANCE_SELECTOR to define what (and how) the appearance delegate can interact with your class.
I say 'need' because it doesn't really seem to be required, but it's hard to be sure...

Some UI elements don't acquire UIAppearance traits

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/

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.

How to change UITabBar Selection color

I need to change the selection color of UITabBar from default blue to red. How do we do this.
Update September 2017:
It's been two years since I've written this answer and since it's receiving upvotes regularly, I should say this is probably the worst possible answer to this question, it's error prone, likely to break because of iOS updates, hard to debug, etc., so please don't do the things I've written and apply better solutions such as subclassing UITabBar or UITabBarController. Thanks.
You can do this by setting a "tintColor" attribute (Key Path) for you UITabBar.
Select the UITabBar in the document outline. (NOT the Controller with the yellow icon.)
Select Identity Inspector in the Utilities area.
Click the + in "User Defined Runtime Attributes."
Add a "tintColor" Key Path of type "Color" and the color you want.
This should do it. You can check it against the screenshot below.
More on this:
There's a "Tint" attribute in Identity Inspector of UITabBar which I believed would do the exact same thing but apparently, it does nothing. It's default value is the exact default fill color when a UITabBarItem is selected, so my guess is it would be fixed in the stable release Xcode 7. Fingers crossed.
In IOS5, UITabBar has a selectedImageTintColor property which does what you need.
In iOS 7 it's simply the tintColor. One way to accomplish this could be to subclass UITabBarViewController, set the custom class in the storyboard, and in your viewDidLoad method of the subclassed tabBarVC add this:
[[self tabBar] setTintColor:[UIColor redColor]];
To achieve above result perform following steps.
Step 1: Add your desired images in Assets.xcassets, and make sure they Render As: Default
Step 2: Select your UITabBar object and set Image Tint color, this color will be selected tab color
Step 3: Select UITabBar object and add Key Path: unselectedItemTintColor, Type: Color, Value: Choose color for unselected item in User Defined Runtime Attributes.
All done.
It is extremely easy
Create a custom class of UITabBarController and in -(void)viewDidLoad method add this line:
[[self tabBar] setSelectedImageTintColor:[UIColor greenColor]];
Because UITextAttributeTextColor is deprecated in iOS 7, you should use:
[UITabBarItem.appearance setTitleTextAttributes:#{NSForegroundColorAttributeName : [UIColor greenColor]} forState:UIControlStateNormal];
[UITabBarItem.appearance setTitleTextAttributes:#{NSForegroundColorAttributeName : [UIColor purpleColor]} forState:UIControlStateSelected];
Starting from iOS 8 it's as simple as:
UITabBar.appearance().tintColor = UIColor.redColor()
Simply change the following property in Interface Builder for the TabBar
Obviously in my case its White.
The SDK does not make this easy, but it is technically possible. Apple apparently believes this to be part of their vision of a consistent look and feel.
UITabBar is a subclass of UIView. You can always subclass and implement your own -drawRect:
This is not a trivial task, however, you have to essentially re-implement the class from scratch or you risk some weird side-effects.
Swift 5 Programatically
It is pretty easy in Swift 5.
In your TabBarController write this:
tintColor = UIColor.red
That's it
I've been searching for a way to set the selected text color of a UITabBarItem and have found a dead simple method, using the UIAppearance protocol.
[UITabBarItem.appearance setTitleTextAttributes:#{
UITextAttributeTextColor : [UIColor greenColor] } forState:UIControlStateNormal];
[UITabBarItem.appearance setTitleTextAttributes:#{
UITextAttributeTextColor : [UIColor purpleColor] } forState:UIControlStateSelected];
Please excuse the awful colors!
iOS 5.0 fixes this issue but the solution is under NDA. Look up UITabBar in your documentation for an EASY way to do what you want to do.
I found the easiest solution -
Select Tab Bar in Tab Bar Controller
Set Image Tint color
Set Tint Color
For reference see the attached image.

Resources