Tutorial Introduction

The purpose of this tutorial is to introduce through play the RBPageViewController and RBPageHeaderViewController components of Redbeard.

The purpose of the tutorial is not to build something useful, but to introduce through tinkering some of the components of Redbeard. As you work your way through the tutorial, feel free to explore and experiment.

Prerequisites

Before you begin this tutorial, you will need to ensure the following prerequisites are met:

  • You have some working knowledge of Cocoa Touch.
  • Create a new Single View Application Xcode project. You may use Swift or Objective-C for development. This tutorial will be using Objective-C.
  • Follow the Redbeard [Getting Started Guide]. to add the Redbeard Framework and the default theme to your project.

You may download the source code to this tutorial.

Theme

Just to familiarize ourselves with themes a little we will make a quick change to the primary colors that have been defined. In your project open the colors.json file. This file is located in at /default/core/colors.json

Change the lines:

"color-primary": "ref://palette-blue-grey-500",
"color-primary-darker": "ref://palette-blue-grey-700",
"color-primary-lighter": "ref://palette-blue-grey-200",

The color references you see here e.g. ref://palette-blue-500 have been defined elsewhere in the file material-design-palette.json. You may assign any colors you like from references or in RGB or RGBA format e.g. "color-primary": "#FF000000"

to:

"color-primary": "ref://palette-blue-300",
"color-primary-darker": "ref://palette-blue-700",
"color-primary-lighter": "ref://palette-blue-200",

Remember there is no reason you cannot do away with the default theme and create your own, laid out as you like

The Page

For the purposes of this demo, we're going to work directly in he ViewController class created by Xcode. For more complicated applications, we may opt instead to add a navigation controller or a container view of some kind.

Let's begin by making ViewController a subclass of RBPageViewController, which will make it a Redbeard page. Be sure to import Redbeard first.

#import <Redbeard/Redbeard.h> // Redbeard
@interface ViewController : RBPageViewController

Adding a Header

RBPageViewController has an optional property name header. To add a header to the page, you must assign a new RBPageHeaderViewController object to this property. Lets go ahead and do this in viewDidLoad:

self.headerViewController = [RBPageHeaderViewController alloc] initWithoutNib];

Screenshot

The header will occupy the space that it needs to properly display it's items, automatically offsetting for the status bar if there is one. Currently there are no items and so it only occupies the status bar plus a margin that is specified in the default theme.

Now that the status bar is now visible over the header. We can update the RBPageViewController.json file to change the status bar style from default to light. Changing it here will mean all RBPageViewController will have this status bar style assigned to it. Let's create a base theme for our view controller and make changes there. To do this add new JSON file named the same as the class name of the view controller. In our case this would be ViewController.json. Then lets write up the theme in the new JSON file inheriting from RBPageViewController. We'll change the statusBarStyle to light.

{
    "ViewController":
    {
        "statusBarStyle": "light",
        "inherits": "ref://RBPageViewController",
    }
}

In the themes section of theme.inc.json add the ViewController.json file:

{
    {
    "include":
    [
        "default.inc.json"
    ],
    "themes":
    [
        "ViewController.json"
    ]
}

Remember the JSON identifer must be the same as the name of the class i.e. ViewController for this theme to be automatically applied.

Screenshot

Header Items

A header can have any number of items added to it. An item can be any view with an alignment left, center or right. Items are automatically sized and positioned as effectively as possible in the space that is available to the header. As is consistent across Redbeard, it also automatically adjusts to changes in container size and orientation.

To add our first item - a centered title label - we should first declare the label itself:

@property (nonatomic) RBLabel *headerTitleLabel;

We create the label in the standard way in viewDidLoad:

self.headerTitleLabel = [RBLabel new];
self.headerTitleLabel.text = @"My Page";

Then an RBPageHeaderItem object must be created:

RBPageHeaderItem *headerTitleItem = 
[[RBPageHeaderItem alloc] initWithThemeIdentifier:@"headerTitleLabel"
                                  alignment:RBPageHeaderItemAlignmentCenter
                                       view:self.headerTitleLabel];

Now we have our first header item, which we can assign to the header like so:

self.headerViewController.items = @[ headerTitleItem ];

To theme the label, we can add the following key to the `ViewController.json` file:

    "header":
    {
        "headerTitleLabel":
        {
            "textColor": "#FFFFFFFF"
        }
    }

Screenshot

Try adjusting the label font size and the item alignment to see what happens. You can also try rotating the user interface to see it adjust.

Adding More Items

Now let's add some more items - two buttons - to the left and right.

First the declarations:

@property (nonatomic) RBButton *addButton;
@property (nonatomic) RBButton *settingsButton;

Then building the items:

self.addButton = [RBButton new];
RBPageHeaderItem *addButtonItem =
[[RBPageHeaderItem alloc] initWithThemeIdentifier:@"addButton"
                                  alignment:RBPageHeaderItemAlignmentRight
                                       view:self.addButton];
self.settingsButton = [RBButton new];
RBPageHeaderItem *settingsButtonItem =
[[RBPageHeaderItem alloc] initWithThemeIdentifier:@"settingsButton"
                                  alignment:RBPageHeaderItemAlignmentLeft
                                       view:self.settingsButton];

Then assigning the items:

self.headerViewController.items = @[ headerTitleItem, addButtonItem, settingsButtonItem ];

Then theming the buttons by adding the following inside of the header section like earlier:

"addButton":
{
    "inherits": "ref://toolbar-button",
    "imageNormal": "glyph://plus-small"
},
"settingsButton":
{
    "inherits": "ref://toolbar-button",
    "imageNormal": "glyph://gears-small"
}

Screenshot

What if we set the alignment of both buttons to right?

Screenshot

Scenario #1 - Overlapping Items

The most common scenario of this kind is where the items aligned left or right spill-over into the space that is needed by the items aligned center. The items with a center alignment will always try to remain in the center of the header, but items on the left or right can push and squeeze the items in the middle.

To provide an example, lets add another item - a label - to the left side of the header...

Declaration:

@property (nonatomic) RBLabel *infoLabel;

Build item:

self.infoLabel = [RBLabel new];
self.infoLabel.text = [RBRandom lorumIpsumWithWordCount:3];
RBPageHeaderItem *infoLabelItem =
[[RBPageHeaderItem alloc] initWithThemeName:@"infoLabel"
                                  alignment:RBPageHeaderItemAlignmentLeft
                                       view:self.infoLabel];

Assign item:

self.headerViewController.items = @[ headerTitleItem, addButtonItem, settingsButtonItem, infoLabelItem ];

Theme item:

"infoLabel":
{
    "textColor": "#FFFFFFFF",
    "font": "ref://standard-caption1-font"
}

Screenshot

Notice that the title label has been pushed to the right. But how would the same header look if the interface was rotated to landscape to provide more header width?

Screenshot

Now there is sufficient space and the title is properly centered again.

Source Code

The source code contains more comments and demonstrates how to add actions to header buttons. You will need to add in the Redbeard Framework to the project after downloading.

Download Source Code