I've figured out how to set the tint for the title bar and have set a background image for all my views, but for the life of me I cannot figure out how to set the default UILabel color for section headers and such. I don't want to riddle my code setting all my colors to UIColor.Black by hand. Is there any way to get a list of different UIElements and the way to set defaults (colors, fonts, sizes) for each? I'm specifically interested in the color of labels, but any other information would be extremely helpful for the future.
-
Can you subclass `UILabel`, and do the work to setup your "default" label there? This way you just use the subclass throughout your code (or XIB files). – jonathanpeppers Apr 30 '12 at 17:44
-
I'm using Monotouch.Dialog, so I don't see a way of controlling those elements, unless I was to copy the source from the assembly view and create my own classes. I'm considering this route if I can't find a way to change the color for the labels in one place. – Derreck Dean Apr 30 '12 at 19:25
-
To elaborate, I would have my own DDRootElement, DDSection, etc. that would set these labels to whatever color I choose. – Derreck Dean Apr 30 '12 at 19:28
2 Answers
Starting with iOS 5 there's an UIAppearance
class to handle global appearance of many UI elements.
The way it works with MonoTouch is that an inner type, called Appearance
, exists on those types. You can directly set the properties from it (easy with MonoDevelop's code completion). E.g.
UILabel.Appearance.BackgroundColor = UIColor.Blue;
Sadly it does not cover everything you might want for every control (nor will it work before iOS 5).

- 43,413
- 6
- 77
- 174
-
Sadly it only lets you change the background color, not the foreground color. However I found a workaround that I will be posting up in a bit. – Derreck Dean May 01 '12 at 14:07
This is kind of hacky, but this does the trick, and it works with all kinds of other UI controls that subclass UIView
. This assumes you have your own subclassed DialogViewController
(mine has lots of handy time-saving things in it, and all my views subclass my DVC to do work).
protected void ForAllSubviewUIControlsOfType<TUIType>(Action<TUIType, int> actionToPerform) where TUIType : UIView
{
processSubviewUIControlsOfType<TUIType>(this.View.Subviews, actionToPerform, 0);
}
private void processSubviewUIControlsOfType<TUIType>(UIView[] views, Action<TUIType, int> actionToPerform, int depth) where TUIType : UIView
{
if (views == null)
return;
if (actionToPerform == null)
return;
foreach (UIView view in views)
{
if (view.GetType () == typeof(TUIType))
{
actionToPerform((TUIType)view, depth);
}
if (view.Subviews != null)
{
foreach (UIView subview in view.Subviews)
{
processSubviewUIControlsOfType<TUIType>(view.Subviews, actionToPerform, depth + 1);
}
}
}
}
To solve the original problem and change the text colors of all labels that are in sections, this is what you need to do:
public override void ViewDidAppear (bool animated)
{
base.ViewDidAppear (animated);
ForAllSubviewUIControlsOfType<UILabel>((label, depth) => {
if ( /*label.Superview is UIView && label.Superview.Superview is UITableView*/ depth == 1 )
{
label.TextColor = UIColor.Black;
}
});
}
The commented out part is what was determining if the label existed inside a section, before I decided to return an int depth
count to see if it was on the view.
EDIT: Seems as if this isn't the perfect solution... the depth count varies for these elements. I'll have to figure out something better in the next day or two.

- 3,708
- 1
- 26
- 45