Matt's Blog

Three20 Stylesheets iPhone Tutorial


Update: This tutorial is outdated, proceed at your own risk.

Introduction to Three20 Stylesheets

In this tutorial, I am going to show you how to use CSS like stylesheets in your iPhone Apps.

If (like me) you’re coming to the iPhone platform from a Web Design perspective, you should be very familiar with CSS and external stylesheets. Unfortunately right now, there is no built-in equivalent to CSS for building iPhone apps.

Lucky for us Joe Hewitt has created a way with his Three20 iPhone Library. With Three20, you can easily change something like this:

A screenshot of my sample App WITHOUT three20 stylesheets

To something like this:

A screenshot of my sample App using three20 stylesheets

Using this stylesheet:

The actual stylesheet in my sample app

Although I am going to show you some cool features of Three20, I’m NOT going to show you how to install Three20 in your Apps, nor build a complete App with Three20. Nope, today I’m only going to show you how to use Three20′s stylesheet capabilities.

I’m assuming a basic knowledge of Three20 and an intermediate knowledge of Cocoa and iPhone Dev. I’m also assuming you already have a UILabel or something to that you want to change the font of.

If you want to get your hands dirty, there is a sample app using this same code on my GitHub Three20 tutorial repository.

Let’s start the show

First things first, create your stylesheet.

  1. Create a new blank file. Do this by going File >> New File, then clicking NSObject Subclass. Name the file “BNDefaultStylesheet” (i like sticking to Three20′s naming conventions by replacing the abbreviation TT with the abbreviation BN for “Basic Navigation”).

    Copy the following code into BNDefaultStylesheet.h:

    #import "Three20/TTStyleSheet.h"
    #import "Three20/TTDefaultStyleSheet.h"
    
    @interface BNDefaultStyleSheet : TTDefaultStyleSheet
    
    @end

    Then copy the following into BNDefaultStylesheet.m:

    #import "BNDefaultStyleSheet.h"
    #import "Three20/TTStyle.h"
    #import "Three20/TTShape.h"
    #import "Three20/TTURLCache.h"
    
    ///////////////////////////////////////////////////////////////////////////////////////////////////
    
    @implementation BNDefaultStyleSheet
    
    @end
  2. Register the new stylesheet into the app delegate. Do this by making BasicNavigationAppDelegate.m look like this:
    #import "BasicNavigationAppAppDelegate.h"
    #import "RootViewController.h"
    #import "Three20/Three20.h"
    #import "BNDefaultStyleSheet.h"
    
    @implementation BasicNavigationAppAppDelegate
    
    @synthesize window;
    @synthesize navigationController;
    
    #pragma mark -
    #pragma mark Application lifecycle
    
    - (void)applicationDidFinishLaunching:(UIApplication *)application {
    
        // Override point for customization after app launch
    
    	[TTStyleSheet setGlobalStyleSheet:[[[BNDefaultStyleSheet alloc]
    										init] autorelease]];
    
    	[window addSubview:[navigationController view]];
        [window makeKeyAndVisible];
    }
    
    - (void)applicationWillTerminate:(UIApplication *)application {
    	// Save data if appropriate
    }
    
    #pragma mark -
    #pragma mark Memory management
    
    - (void)dealloc {
    	[navigationController release];
    	[window release];
    	[super dealloc];
    }
    
    @end
  3. Make your first font style. Add a new font style and color by making BNDefaultStylesheet.h look like this:
    #import "Three20/TTStyleSheet.h"
    #import "Three20/TTDefaultStyleSheet.h"
    
    @interface BNDefaultStyleSheet : TTDefaultStyleSheet
    
    @property(nonatomic,readonly) UIColor* myFirstColor;
    @property(nonatomic,readonly) UIFont* myFirstFont;
    
    @end

    And making BNDefaultStylesheet.m look like this:

     

    #import "BNDefaultStyleSheet.h"
    #import "Three20/TTStyle.h"
    #import "Three20/TTShape.h"
    #import "Three20/TTURLCache.h"
    
    ///////////////////////////////////////////////////////////////////////////////////////////////////
    
    @implementation BNDefaultStyleSheet
    
    ///////////////////////////////////////////////////////////////////////////////////////////////////
    // styles
    
    ///////////////////////////////////////////////////////////////////////////////////////////////////
    // public colors
    
    - (UIColor*)myFirstColor {
    	return RGBCOLOR(80, 110, 140);
    }
    
    - (UIColor*)mySecondColor {
    	return [UIColor grayColor];
    }
    
    ///////////////////////////////////////////////////////////////////////////////////////////////////
    // public fonts
    
    - (UIFont*)myFirstFont {
    	return [UIFont boldSystemFontOfSize:15];
    }
    
    - (UIFont*)mySecondFont {
    	return [UIFont systemFontOfSize:14];
    }
    
    @end
  4. Use your new style. Change the font to point to the font style by making BNCell.m look like this:
    #import "BNCell.h"
    #import "BNDefaultStylesheet.h"
    
    ///////////////////////////////////////////////////////////////////////////////////////////////////
    
    /////////////////////////////////////////
    //////   BNSubtextTableFieldCell     ////
    /////////////////////////////////////////
    
    @implementation BNSubtextTableFieldCell
    
    ///////////////////////////////////////////////////////////////////////////////////////////////////
    
    - (void)setObject:(id)object {
    	if (_field != object) {
    		[super setObject:object];
    
    		TTSubtextTableField* field = object;
    		_label.text = field.text;
    		_label.font = TTSTYLEVAR(myFirstFont);
    		_label.textColor = TTSTYLEVAR(myFirstColor);
    		_label.adjustsFontSizeToFitWidth = YES;
    
    		_subtextLabel.text = field.subtext;
    	}
    }
    
    @end
    
    ///////////////////////////////////////////////////////////////////////////////////////////////////

Voila! You should now have your first App using Three20 Stylesheets. Your App should now have blue labels instead of black ones like so:

A screenshot of my sample App WITH three20 stylesheets

I’ll be refining this tutorial in the future, but if you find any glaring omissions please point em out.

AND To people following my tutorials: … DON’T BE SO PROUD. Ask questions if you have em, I’m cool with helping you get this stuff working in your Apps.

Posted on - Archive

My name is Matt Vague and I'm a Front End Developer from Vancouver, Canada. I'm passionate about beautiful, responsive user interfaces and I'm a Front End-Developer at VersaPay, core team member of ActiveAdmin and the creator of BC Liquor Locator.