iOS Development with Xamarin Cookbook
上QQ阅读APP看书,第一时间看更新

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.

Note

The downloadable code contains a separate project for this recipe. It is named CustomViewApp2.

How to do it…

Perform the following steps to complete this recipe:

  1. Open the CustomViewAppViewController.xib file in Xcode.
  2. Resize the MyView object, which we created earlier, to make some room at the top.
  3. Add a UILabel above the MyView object. Make sure that the label is added on the main view and not on MyView.
  4. Connect both objects to their respective outlets.
  5. Back in Xamarin Studio, add the following code in the ViewDidLoad method of CustomViewAppViewController:
    UILabel.Appearance.BackgroundColor = UIColor.Blue;
    var labelStyle = UILabel.AppearanceWhenContainedIn(typeof(MyView));
    labelStyle.BackgroundColor = UIColor.Green;
  6. Compile and run the app on the simulator. The output should be similar to the one shown in the following screenshot:
    How to do it…

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.

Limitations of UIAppearance

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