
Styling views
iOS provides a set of APIs through the UIAppearance protocol that allows us to adjust the appearance of the views once, without having to explicitly modify the styling properties on every instance of each view. This is particularly useful if, say, we want a specific view to have the same appearance throughout the app.
Apart from setting the styling properties of a view globally, we can also define the appearance of this view to be different under certain circumstances. Read on to find out how to accomplish this.
Getting ready
We will work on the existing CustomViewApp
project we created in the preceding recipe. Open the project in Xamarin Studio.
How to do it…
Perform the following steps to complete this recipe:
- Open the
CustomViewAppViewController.xib
file in Xcode. - Resize the
MyView
object, which we created earlier, to make some room at the top. - Add a
UILabel
above theMyView
object. Make sure that the label is added on the main view and not onMyView
. - Connect both objects to their respective outlets.
- Back in Xamarin Studio, add the following code in the
ViewDidLoad
method ofCustomViewAppViewController
:UILabel.Appearance.BackgroundColor = UIColor.Blue; var labelStyle = UILabel.AppearanceWhenContainedIn(typeof(MyView)); labelStyle.BackgroundColor = UIColor.Green;
- Compile and run the app on the simulator. The output should be similar to the one shown in the following screenshot:
How it works…
The UIAppearance
class is basically a proxy to the specific properties of each control. In Xamarin.iOS, we can access each control's proxy through its static Appearance
property. The changes we make to this object's properties will reflect on the instances of the object throughout the app. In this case, we set the BackgroundColor
attribute of all UILabel
instances to blue using the following code:
UILabel.Appearance.BackgroundColor = UIColor.Blue;
However, we can provide different behavior for specific instances of UILabel
. For example, we want the labels that are contained in MyView
objects to have a green background. We accomplish this by calling the static AppearanceWhenContainedIn
method, as shown in the following code:
var labelStyle = UILabel.AppearanceWhenContainedIn(typeof(MyView));
We pass the types of objects for which we want to set the specific style. In this case, passing typeof(MyView)
instructs the appearance proxy to make sure that we are referring to objects that are only contained in MyView
objects. We then set the value we want to the object that was returned from this method, as shown in the following code:
labelStyle.BackgroundColor = UIColor.Green;
There's more…
Through the AppearanceWhenContainedIn
method, we can target a more specific set of styling. For example, consider the following line of code:
var labelStyle = UILabel.AppearanceWhenContainedIn(typeof(AnotherView), typeof(MyView));
This would return a styling object that acts as a proxy for all instances of UILabel
, which are part of MyView
, only when MyView
is included in AnotherView
objects.
The UIAppearance
protocol has some limitations, which are as follows:
- Only specific properties can be set. For example, we cannot set the
Frame
of a view globally. Each set of properties that can be changed for a control can be accessed through its appearance proxy. If a control property is not in the appearance proxy, we cannot modify it for all instances of that particular control. - For modifying the appearance of a custom view (in this case,
MyView
), using the following line of code will yield an unwanted result:MyView.Appearance.BackgroundColor = UIColor.Yellow;
That is, all instances of UIView
will have a yellow background. This is because C# cannot override the static methods in derived classes. To overcome this issue, we use the GetAppearance<T>
static method on the derived class instead, as shown in the following code:
MyView.GetAppearance<MyView>().BackgroundColor = UIColor.Yellow; // We can also call GetAppearance on the base class: //UIView.GetAppearance<MyView>().BackgroundColor = UIColor.Yellow;
See also
- The Creating a custom view recipe
- The Creating a custom view controller recipe in Chapter 3, User Interface – View Controllers