<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Matt&#039;s Portfolio</title>
	<atom:link href="http://www.mattvague.com/feed" rel="self" type="application/rss+xml" />
	<link>http://www.mattvague.com</link>
	<description>Just another WordPress site</description>
	<lastBuildDate>Tue, 15 Nov 2011 05:27:37 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>BC Liquor Locator iPhone App, now available in the App Store</title>
		<link>http://www.mattvague.com/bc-liquor-locator-iphone-app-now-available-in-app-store</link>
		<comments>http://www.mattvague.com/bc-liquor-locator-iphone-app-now-available-in-app-store#comments</comments>
		<pubDate>Thu, 10 Jun 2010 05:35:24 +0000</pubDate>
		<dc:creator>MattV</dc:creator>
				<category><![CDATA[Apple]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Society]]></category>
		<category><![CDATA[Three20]]></category>

		<guid isPermaLink="false">http://mattvague.com/?p=1308</guid>
		<description><![CDATA[This is a quick one: My first iPhone App (BC Liquor Locator) was just approved for sale in App Store. The concept is simple: find the closest open liquor store to you, anywhere in BC instantly. Open the app and see a list of BC Liquor stores near you, how far they are away from [...]]]></description>
			<content:encoded><![CDATA[<p><strong>This is a quick one: My first iPhone App (BC Liquor Locator) was just approved for sale in App Store.</strong></p>
<p>The concept is simple: find the closest open liquor store to you, anywhere in BC instantly. Open the app and see a list of BC Liquor stores near you, how far they are away from you and whether they&#8217;re still open. A complete listing of each and every store&#8217;s hours are just a click away from their, not to mention a map view of all BC Liquor Stores.</p>
<p><a href="itms://itunes.apple.com/ca/app/bc-liquor-locator/id368167119?mt=8" target="_blank">itms://itunes.apple.com/ca/app/bc-liquor-locator/id368167119?mt=8</a></p>
<p><a href="http://mattvague.com/wordpress/wp-content/uploads/2010/06/app_big_phone.jpg"><img class="alignnone size-full wp-image-1317" title="app_big_phone" src="http://mattvague.com/wordpress/wp-content/uploads/2010/06/app_big_phone.jpg" alt="app_big_phone" width="312" height="516" /></a></p>
<p>&nbsp;</p>
<p><strong>For you iPhone Devs out there:</strong> This app was built using several components of the <a href="github.com/facebook/three20">Three20 iPhone Library</a>.</p>
<p>Here is a bunch of good links related to Three20</p>
<p>GitHub: <a href="http://www.facebook.com/widgets/like.php?href=http://three20.info/">http://github.com/facebook/three20</a></p>
<p>Google Group: <a href="http://groups.google.com/group/three20/">http://groups.google.com/group/three20/</a></p>
<p>Documentation: <a href="http://three20.info/">http://three20.info/</a></p>
<p>And I even have some Three20 tutorials on my own site, checkout the <a href="http://mattvague.com/blog/three20">Three20 section</a> of my <a href="http://mattvague.com/blog">blog</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.mattvague.com/bc-liquor-locator-iphone-app-now-available-in-app-store/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Three20 TTTableItem Tutorial</title>
		<link>http://www.mattvague.com/three20-tttableitem-tutorial</link>
		<comments>http://www.mattvague.com/three20-tttableitem-tutorial#comments</comments>
		<pubDate>Sun, 23 Aug 2009 00:50:24 +0000</pubDate>
		<dc:creator>MattV</dc:creator>
				<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Three20]]></category>
		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://mattvague.com/?p=979</guid>
		<description><![CDATA[Update: This tutorial is outdated, proceed at your own risk. &#8212; Say Hello to Three20 TTTableItemCells Over the last couple of months I&#8217;ve shown you how to use Joe Hewitt&#8217;s Three20 iPhone library to create css-like stylesheets for your iPhone Apps, as well as custom table cells for your iPhone Apps. But a while ago Joe [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: left;"><strong>Update:</strong> This tutorial is outdated, proceed at your own risk.</p>
<p>&#8212;</p>
<h2>Say Hello to Three20 TTTableItemCells</h2>
<p>Over the last couple of months I&#8217;ve shown you how to use <a title="Joe Hewitt's blog" href="http://www.joehewitt.com/" target="_blank">Joe Hewitt&#8217;s</a> <a href="http://github.com/joehewitt/three20/tree/master">Three20 iPhone library </a>to create <a href="http://mattvague.com/three20-stylesheets-tutorial">css-like stylesheets</a> for your iPhone Apps, as well as <a href="http://mattvague.com/three20-custom-cells-iphone-tutorial">custom table cells</a> for your iPhone Apps.</p>
<p>But a while ago Joe changed up the way we make custom table cells. Instead of using TTTableField and TTTableFieldCell we now use TTTableItem and TTTableItemCell to accomplish custom table cells.</p>
<p>So today I am going to show you how to create an iPhone App using Three20&#8242;s TTTableItem and TTTableItemCell.</p>
<h2>Lets start the show</h2>
<p>Here&#8217;s our game plan for creating our custom cells:</p>
<ol>
<li>Setup our App, create some necessary files, etc</li>
<li>Make our own TableItems by subclassing TTTableItem</li>
<li>Make our own TableItemCells by subclassing TTTableItemCell</li>
<li>Instantiate our new TableItems in our DataSource</li>
<li>Make the App render the correct TableItemCell for each TableItem we just made</li>
<li>Finally when we&#8217;ve done all the other stuff, we&#8217;ll have a sexy new app with sexy custom table cells</li>
</ol>
<h3>1. Setup the App</h3>
<p>I think the easiest way to learn how to do this is too follow along step by step with this tutorial (i&#8217;ve created a three20 App template that works great for this)</p>
<ol>
<li>Download or Clone my <a href="http://github.com/mattvague/three20-iPhone-tutorials/tree/master">Three20 Tutorial repository</a> from github</li>
<li>When my repo is downloaded or cloned open it and copy and past the basic-navigation-app-template somewhere else on your computer (if you want)The three20-iPhone-tutorials folder should now look like this:</li>
<li><img class="alignnone size-full wp-image-1161" title="Picture 14" src="http://mattvague.com/wordpress/wp-content/uploads/2009/08/Picture-14.png" alt="Picture 14" width="335" height="113" /></li>
<li>Rename basic-navigation-app-template copy folder to something like tableitem-tutorial-working</li>
<li>Open the Xcode Project file inside of your new folder (again we&#8217;re using a template App that I created)</li>
<li>Now we need to create some new classes inside of XCode:
<ol>
<li>We need a new class that will subclass TTTableItem. Go File &gt;&gt; New File &gt;&gt; Objective-C Class &gt;&gt; Name it BNTableItem (following Joe&#8217;s naming conventions). Make sure &#8220;Also create BNTableItem.h&#8221; is checked.</li>
<li>We also need a new class where we will sublclass TTTableItemCell. Go File &gt;&gt; New File &gt;&gt; Objective-C Class &gt;&gt; Name it BNTableItemCell (following Joe&#8217;s naming conventions). Make sure &#8220;Also create BNTableItemCell.h&#8221; is checked.</li>
</ol>
</li>
<li>Now that our all of our files are created let&#8217;s give our App a title. Go into RootViewController.mand change the lineself.title = @&#8221;Tutorial Title&#8221;;toself.title = @&#8221;TableItem Tutorial&#8221;;.<strong>RootViewController.m</strong>should now look like this:
<pre name="code" class="objc">#import "RootViewController.h"

#pragma mark import dataSource
#import "RootViewDataSource.h"

# pragma mark import table cells

@implementation RootViewController

///////////////////////////////////////////////////////////////////////////////////////////////////
// UIViewController

- (void)loadView {
    [super loadView];

    self.tableView = [[[UITableView alloc] initWithFrame:self.view.bounds
                                                   style:UITableViewStyleGrouped] autorelease];
    self.tableView.autoresizingMask = UIViewAutoresizingFlexibleWidth
    | UIViewAutoresizingFlexibleHeight;
    self.variableHeightRows = YES;
    self.title = @"TableItem Tutorial";
    [self.view addSubview:self.tableView];
}

//////////////////////////////////////////////////////////////////////////////////////////////////
// TTTableViewController

- (id)createDataSource {
    return [RootViewDataSource rootViewDataSource];
}

@end</pre>
</li>
<li><strong><span style="font-weight: normal;">Make sure that you have selected </span>Device 3.0<span style="font-weight: normal;"> or </span>Simulator 3.0<span style="font-weight: normal;"> to run the app</span></strong></li>
<li>Open the App and see what happens. Click <strong>Build and Go</strong> (or <strong>Build</strong> &gt;&gt; <strong>Build and Go (Run)</strong>).The App should look like this (nothing special yet, but just you wait):</li>
<li><a href="http://mattvague.com/wordpress/wp-content/uploads/2009/08/Picture-1.png"><img class="alignnone size-full wp-image-1209" title="Picture 1" src="http://mattvague.com/wordpress/wp-content/uploads/2009/08/Picture-1.png" alt="Picture 1" width="154" height="232" /></a></li>
</ol>
<h3>2. Subclass TTTableItem</h3>
<p>Now we need to make our TableItem. To do this we are going to subclass TTTableCaptionedItem.</p>
<p>TableItems hold the data, TableItemCells actually display the data.</p>
<p>Sink that into your head, it&#8217;s important:</p>
<p>TableItems holds the data, TableItemCells display.</p>
<p>Do the following steps, once they are done I will explain what was accomplished.</p>
<ol>
<li>Go into <strong>BNTableItem.h</strong> and delete everything</li>
<li>Go into <strong>BNTableItem.m</strong> and delete everything</li>
<li>Now we need to subclass TTTableCaptionedItem because it&#8217;s quite similar to what we are trying to accomplish, but needs some enhancements. Copy and paste this code into the empty <strong>BNTableItem.h</strong>file:
<pre name="code" class="objc">#import "Three20/Three20.h"

///////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////
//////   BNTableCaptionedItemWithThreeImagesBelow  /////
////////////////////////////////////////////////////////

@interface BNTableCaptionedItemWithThreeImagesBelow : TTTableCaptionedItem {

}

@end</pre>
</li>
<li>Now copy and paste this code into<strong> BNTableItem.m</strong>:
<pre name="code" class="objc">#import "BNTableItem.h"

///////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////
//////   BNTableCaptionedItemWithThreeImagesBelow  /////
////////////////////////////////////////////////////////

@implementation BNTableCaptionedItemWithThreeImagesBelow

@end</pre>
</li>
</ol>
<p>We just created a subclass of  TTTableCaptionedItem which we named <strong>BNTableCaptionedItemWithThreeImagesBelow</strong>.</p>
<p>But we haven&#8217;t changed anything in our class yet, let&#8217;s do that now:</p>
<ol>
<li>Go back to <strong>BNTableItem.h</strong>and modify it so the file looks exactly like this:
<pre name="code" class="objc">#import "Three20/Three20.h"

///////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////
//////   BNTableCaptionedItemWithThreeImagesBelow  /////
////////////////////////////////////////////////////////

@interface BNTableCaptionedItemWithThreeImagesBelow : TTTableCaptionedItem {
	NSString* _image1;
	NSString* _image2;
	NSString* _image3;
	TTStyle* _imageStyle;
}

@property(nonatomic,copy) NSString* image1;
@property(nonatomic,copy) NSString* image2;
@property(nonatomic,copy) NSString* image3;
@property(nonatomic,retain) TTStyle* imageStyle;

+ (id)itemWithText:(NSString*)text caption:(NSString*)caption image1:(NSString*)image1 image2:(NSString*)image2 image3:(NSString*)image3;

@end</pre>
</li>
<li>Go to back to <strong>BNTableItem.m </strong>and <strong>modify it</strong>so the file looks exactly like this:
<pre name="code" class="objc">#import "BNTableItem.h"

///////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////
//////   BNTableCaptionedItemWithThreeImagesBelow  /////
////////////////////////////////////////////////////////

@implementation BNTableCaptionedItemWithThreeImagesBelow
@synthesize image1 = _image1, image2 = _image2, image3 = _image3, imageStyle = _imageStyle;

///////////////////////////////////////////////////////////////////////////////////////////////////
// class public

+ (id)itemWithText:(NSString*)text caption:(NSString*)caption image1:(NSString*)image1 image2:(NSString*)image2 image3:(NSString*)image3 {
		BNTableCaptionedItemWithThreeImagesBelow* item = [[[self alloc] init] autorelease];
		item.text = text;
		item.caption = caption;
		item.image1 = image1;
		item.image2 = image2;
		item.image3 = image3;
		return item;
	}

///////////////////////////////////////////////////////////////////////////////////////////////////
// NSObject

- (id)init {
	if (self = [super init]) {
		_image1 = nil;
		_image2 = nil;
		_image3 = nil;
		_imageStyle = nil;
	}
	return self;
}

- (void)dealloc {
	TT_RELEASE_MEMBER(_image1);
	TT_RELEASE_MEMBER(_image2);
	TT_RELEASE_MEMBER(_image3);
	TT_RELEASE_MEMBER(_imageStyle);
	[super dealloc];
}

///////////////////////////////////////////////////////////////////////////////////////////////////
// NSCoding

- (id)initWithCoder:(NSCoder*)decoder {
	if (self = [super initWithCoder:decoder]) {
		self.image1 = [decoder decodeObjectForKey:@"image1"];
		self.image2 = [decoder decodeObjectForKey:@"image2"];
		self.image3 = [decoder decodeObjectForKey:@"image3"];
	}
	return self;
}

- (void)encodeWithCoder:(NSCoder*)encoder {
	[super encodeWithCoder:encoder];
	if (self.image1) {
		[encoder encodeObject:self.image1 forKey:@"image1"];
	}
	if (self.image2) {
		[encoder encodeObject:self.image2 forKey:@"image2"];
	}
	if (self.image3) {
		[encoder encodeObject:self.image3 forKey:@"image3"];
	}
}

@end</pre>
</li>
</ol>
<p>Finished? Awesome. I am not going to explain everything that we did there, but I will give an overview.</p>
<ul>
<li>We added 3 new properties to our class (one for each image)</li>
<li>We made a method called<strong> </strong><strong>+ (id)itemWithText:(NSString*)text caption:(NSString*)caption image1:(NSString*)image1 image2:(NSString*)image2 image3:)</strong> which accepts the addresses for each of the 3 images as well as our text content</li>
<li>We added the 3 image properties to the<strong> init </strong>method<strong>, </strong>the<strong> initWithCoder </strong>method<strong>, </strong>and<strong> encodeWithCoder </strong>method<strong>.</strong></li>
</ul>
<p>The BNTableItem part of this tutorial is now finished.</p>
<p>The next part of our tutorial deals with displaying the data from our TableItem (the labels, images, etc), lets get started</p>
<h3>3. Subclass TTTableItemCell</h3>
<p>Subclassing TTTableCaptionedItemCell (itself a subclass of TTTableItemCell) will be similar to the subclassing we just did of TTTableCaptionedItem.</p>
<ol>
<li>Go into <strong>BNTableItemCell.h</strong> and delete everything</li>
<li>Go into <strong>BNTableItemCell.m</strong> and delete everything</li>
<li>We should now have NOTHING in either <strong>BNTableItemCell.h</strong> or <strong>BNTableItemCell.m</strong></li>
<li>Now subclass TTTableCaptionedItemCell. Go into and <strong>BNTableItemCell.h</strong>and make it look like this:
<pre name="code" class="objc">#import "Three20/Three20.h"

///////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////
//////   BNTableCaptionedItemWithThreeImagesBelowCell     //
////////////////////////////////////////////////////////////

@interface BNTableCaptionedItemWithThreeImagesBelowCell : TTTableCaptionedItemCell {
  TTImageView* _imageView1;
  TTImageView* _imageView2;
  TTImageView* _imageView3;
}

@end</pre>
</li>
<li>Then go into <strong>BNTableItemCell.m</strong>and make it look like this:
<pre name="code" class="objc">#import "BNTableItemCell.h"
#import "BNTableItem.h"
#import "BNDefaultStylesheet.h"

///////////////////////////////////////////////////////////////////////////////////////////////////

static CGFloat kHPadding = 10;
static CGFloat kVPadding = 15;
static CGFloat kImageWidth = 80;
static CGFloat kImageHeight = 80;

///////////////////////////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////
//////   BNTableCaptionedItemWithThreeImagesBelowCell     ////
//////////////////////////////////////////////////////////////

@implementation BNTableCaptionedItemWithThreeImagesBelowCell

+ (CGFloat)tableView:(UITableView*)tableView rowHeightForItem:(id)item {
	BNTableCaptionedItemWithThreeImagesBelow* captionedItem = item;

	CGFloat maxWidth = tableView.width - kHPadding*2;

	CGSize textSize = [captionedItem.text sizeWithFont:TTSTYLEVAR(myHeadingFont)
					   constrainedToSize:CGSizeMake(maxWidth, CGFLOAT_MAX)
					   lineBreakMode:UILineBreakModeWordWrap];
	CGSize subtextSize = [captionedItem.caption sizeWithFont:TTSTYLEVAR(mySubtextFont)
						  constrainedToSize:CGSizeMake(maxWidth, CGFLOAT_MAX) lineBreakMode:UILineBreakModeWordWrap];

	return kVPadding*2 + textSize.height + subtextSize.height + kImageHeight + kVPadding;
}

///////////////////////////////////////////////////////////////////////////////////////////////////

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString*)identifier {
	if (self = [super initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:identifier]) {
		_item = nil;

		_imageView1 = [[TTImageView alloc] initWithFrame:CGRectZero];
		[self.contentView addSubview:_imageView1];

		_imageView2 = [[TTImageView alloc] initWithFrame:CGRectZero];
		[self.contentView addSubview:_imageView2];

		_imageView3 = [[TTImageView alloc] initWithFrame:CGRectZero];
		[self.contentView addSubview:_imageView3];

	}
	return self;
}

- (void)dealloc {
	TT_RELEASE_MEMBER(_imageView1);
	TT_RELEASE_MEMBER(_imageView2);
	TT_RELEASE_MEMBER(_imageView3);
	[super dealloc];
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// UIView

- (void)layoutSubviews {
	[super layoutSubviews];

	[self.detailTextLabel sizeToFit];
	self.detailTextLabel.top = kVPadding;

	self.textLabel.height = self.detailTextLabel.height;

	_imageView1.frame = CGRectMake(20, self.detailTextLabel.bottom + kVPadding, kImageWidth, kImageHeight);
	_imageView2.frame = CGRectMake(_imageView1.right + kHPadding, self.detailTextLabel.bottom + kVPadding, kImageWidth, kImageHeight);
	_imageView3.frame = CGRectMake(_imageView2.right + kHPadding, self.detailTextLabel.bottom + kVPadding, kImageWidth, kImageHeight);

}

///////////////////////////////////////////////////////////////////////////////////////////////////
// TTTableViewCell

- (id)object {
	return _item;
}

- (void)setObject:(id)object {
	if (_item != object) {
		[super setObject:object];

		BNTableCaptionedItemWithThreeImagesBelow* item = object;

		self.textLabel.textColor = TTSTYLEVAR(myHeadingColor);
		self.textLabel.font = TTSTYLEVAR(myHeadingFont);
		self.textLabel.textAlignment = UITextAlignmentRight;
		self.textLabel.contentMode = UIViewContentModeCenter;
		self.textLabel.lineBreakMode = UILineBreakModeWordWrap;
		self.textLabel.numberOfLines = 0;

		self.detailTextLabel.textColor = TTSTYLEVAR(mySubtextColor);
		self.detailTextLabel.font = TTSTYLEVAR(mySubtextFont);
		self.detailTextLabel.textAlignment = UITextAlignmentLeft;
		self.detailTextLabel.contentMode = UIViewContentModeTop;
		self.detailTextLabel.lineBreakMode = UILineBreakModeWordWrap;

		_imageView1.URL = item.image1;
		_imageView1.style = item.imageStyle;

		_imageView2.URL = item.image2;
		_imageView2.style = item.imageStyle;

		_imageView3.URL = item.image3;
		_imageView3.style = item.imageStyle;

    }
}

@end</pre>
</li>
</ol>
<p>Awesome, we&#8217;re on a roll, we just subclassed TTTableCaptionedItemCell, then modified it so that it has 3 image views underneath the heading and caption.</p>
<ul>
<li>In the <strong>rowHeightForItem</strong> method we made our cell adjust it&#8217;s size to the text content AND our new images.</li>
<li>In the <strong>initWithStyle</strong> method we allocated 3 TTImageViews (to hold our images) and added the TTImageViews as subviews of our main view.</li>
<li>in the <strong>layoutSubviews </strong>method we  made the textLabel (the heading label) and the detailTextLabel (the subtext label) fit together nicely, as well as sizing all three images and making them fit nice and centered underneath the text.</li>
<li>Finally in the <strong>setObject </strong>method<strong> </strong>we set the textColor, the font, and a few other important properties of our textLabel, and detailTextLabel, and we gave each of our 3 TTImageViews the URL of the image their supposed to display (the URL of each TTImageView should match the corresponding URL given for each address we are fed to our TTTableItem).</li>
</ul>
<p>Now we need to put our feed our TableItems to our TableView datasource</p>
<h3>4. Add Our TableItems to the DataSource</h3>
<p>Now what we&#8217;re going to do is instantiate and feed BNTableCaptionedItemWithThreeImagesBelow into our DataSource a few times while feeding it some text content and image addresses.</p>
<ol>
<li>To instantiate and feed our Tableitem into our datasource (twice), make <strong>RootViewDataSource.m</strong>look exactly like this:
<pre name="code" class="objc">#import "RootViewDataSource.h"
#import "BNTableItem.h"
#import "BNTableItemCell.h"

@implementation RootViewDataSource

///////////////////////////////////////////////////////////////////////////////////////////////////
// public

+ (RootViewDataSource*)rootViewDataSource {
	RootViewDataSource* dataSource =  [[[RootViewDataSource alloc] initWithItems:
										[NSMutableArray arrayWithObjects: [BNTableCaptionedItemWithThreeImagesBelow itemWithText:@"These are some pictures of me (Matt) doing different stuff"
																									caption:@"Matt"
																									image1:@"http://mattvague.com/wordpress/wp-content/uploads/2009/08/boating.jpg"
																									image2:@"http://mattvague.com/wordpress/wp-content/uploads/2009/08/cooking.jpg"
																									image3:@"http://mattvague.com/wordpress/wp-content/uploads/2009/08/surfing.jpg"],
																		 [BNTableCaptionedItemWithThreeImagesBelow itemWithText:@"These are some pictures of Vancouver, BC"
																									caption:@"VanCity"
																									image1:@"http://mattvague.com/wordpress/wp-content/uploads/2009/08/Vancouver_Aerial.jpg"
																									image2:@"http://mattvague.com/wordpress/wp-content/uploads/2009/08/Coast-Mountains-BC.jpg"
																									image3:@"http://mattvague.com/wordpress/wp-content/uploads/2009/08/Vancouver_Aerial_2.jpg"],
																		 nil]] autorelease];
	return dataSource;
}

///////////////////////////////////////////////////////////////////////////////////////////////////

- (void)dealloc {
	[super dealloc];
}

///////////////////////////////////////////////////////////////////////////////////////////////////
// TTTableViewDataSource

- (Class)tableView:(UITableView*)tableView cellClassForObject:(id) object {

	if ([object isKindOfClass:[BNTableCaptionedItemWithThreeImagesBelow class]]) {
		return [BNTableCaptionedItemWithThreeImagesBelowCell class];
	} else {
		return [super tableView:tableView cellClassForObject:object];
	}
}

- (void)tableView:(UITableView*)tableView prepareCell:(UITableViewCell*)cell
forRowAtIndexPath:(NSIndexPath*)indexPath {
	cell.accessoryType = UITableViewCellAccessoryNone;
}

@end</pre>
</li>
<li>Now try<strong> launching the App </strong>again<strong>. </strong></li>
</ol>
<p>Looks kinda weird doesn&#8217;t it? That&#8217;s because we need to do one last thing which is to tell our App which kind of TableItemCell to render for our TableItems.</p>
<p>Right now the App is just rendering the closest matching TableItemCell it could find, but not the one that we want (which is the one we just created).</p>
<h3>5. Render the correct TableItemCell for our TableItems</h3>
<p>This part is very simple, and I probably could have combined it with the last step, but it is something that is quite vital and I think deserves its own step.</p>
<ol>
<li><strong>Add the following code</strong> to <strong>RootViewDataSource.m</strong>, underneath the rootViewDataSource, and dealloc methods:
<pre name="code" class="objc">///////////////////////////////////////////////////////////////////////////////////////////////////
// TTTableViewDataSource

- (Class)tableView:(UITableView*)tableView cellClassForObject:(id) object {

	if ([object isKindOfClass:[BNTableCaptionedItemWithThreeImagesBelow class]]) {
		return [BNTableCaptionedItemWithThreeImagesBelowCell class];
	} else {
		return [super tableView:tableView cellClassForObject:object];
	}
}</pre>
</li>
<li>Now <strong>RootViewDataSource.m</strong>should look exactly like this:
<pre name="code" class="objc">#import "RootViewDataSource.h"
#import "BNTableItem.h"
#import "BNTableItemCell.h"

@implementation RootViewDataSource

///////////////////////////////////////////////////////////////////////////////////////////////////
// public

+ (RootViewDataSource*)rootViewDataSource {
	RootViewDataSource* dataSource =  [[[RootViewDataSource alloc] initWithItems:
										[NSMutableArray arrayWithObjects: [[BNTableCaptionedItemWithThreeImagesBelow itemWithText:@"These are some pictures of me (Matt) doing different stuff"
																									caption:@"Matt"
																									image1:@"http://mattvague.com/wordpress/wp-content/uploads/2009/08/boating.jpg"
																									image2:@"http://mattvague.com/wordpress/wp-content/uploads/2009/08/cooking.jpg"
																									image3:@"http://mattvague.com/wordpress/wp-content/uploads/2009/08/surfing.jpg"] autorelease],
																		 [[BNTableCaptionedItemWithThreeImagesBelow itemWithText:@"These are some pictures of Vancouver, BC"
																									caption:@"VanCity"
																									image1:@"http://mattvague.com/wordpress/wp-content/uploads/2009/08/Vancouver_Aerial.jpg"
																									image2:@"http://mattvague.com/wordpress/wp-content/uploads/2009/08/Coast-Mountains-BC.jpg"
																									image3:@"http://mattvague.com/wordpress/wp-content/uploads/2009/08/Vancouver_Aerial_2.jpg"] autorelease]
																			,nil]] autorelease];
	return dataSource;
}

///////////////////////////////////////////////////////////////////////////////////////////////////

- (void)dealloc {
	[super dealloc];
}

///////////////////////////////////////////////////////////////////////////////////////////////////
// TTTableViewDataSource

- (Class)tableView:(UITableView*)tableView cellClassForObject:(id) object {

	if ([object isKindOfClass:[BNTableCaptionedItemWithThreeImagesBelow class]]) {
		return [BNTableCaptionedItemWithThreeImagesBelowCell class];
	} else {
		return [super tableView:tableView cellClassForObject:object];
	}
}

- (void)tableView:(UITableView*)tableView prepareCell:(UITableViewCell*)cell
forRowAtIndexPath:(NSIndexPath*)indexPath {
	cell.accessoryType = UITableViewCellAccessoryNone;
}

@end</pre>
</li>
</ol>
<p><span class="Apple-style-span" style="font-size: 15px; font-weight: bold;">6. Run the App</span></p>
<p><strong>Run our App by clicking on &#8220;Build and Go&#8221; </strong></p>
<p>It should look like this:</p>
<p><a href="http://mattvague.com/wordpress/wp-content/uploads/2009/08/Picture-4.png"><img class="alignnone size-full wp-image-1183" title="Picture 4" src="http://mattvague.com/wordpress/wp-content/uploads/2009/08/Picture-4.png" alt="Picture 4" width="193" height="288" /></a></p>
<h2>Download the working version</h2>
<p>If you are having trouble or just want to checkout the source code, the final working version of my tutorial is <a href="http://github.com/mattvague/three20-iPhone-tutorials">availbile on github</a>. Download or clone my repo and then open the tableitem-tutorial folder and open its Xcode Project.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mattvague.com/three20-tttableitem-tutorial/feed</wfw:commentRss>
		<slash:comments>65</slash:comments>
		</item>
		<item>
		<title>Three20 Custom Cells iPhone Tutorial</title>
		<link>http://www.mattvague.com/three20-custom-cells-iphone-tutorial</link>
		<comments>http://www.mattvague.com/three20-custom-cells-iphone-tutorial#comments</comments>
		<pubDate>Thu, 25 Jun 2009 05:26:25 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Three20]]></category>
		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://mattvague.com/?p=577</guid>
		<description><![CDATA[In my last tutorial I showed you how to use CSS-like stylesheets in your iPhone Apps. Although I did make a custom cell I didn't really show how this is done, and I've decided to go into a bit more detail.

In this tutorial I am going to show you how to make custom table cells in your iPhone Apps using Joe Hewitt's Three20 library.]]></description>
			<content:encoded><![CDATA[<p><strong>Update:</strong> This tutorial is outdated, proceed at your own risk.</p>
<p>&#8212;</p>
<h2>Introduction to custom three20 cells</h2>
<p>In my <a href="http://mattvague.com/three20-stylesheets-tutorial" target="_blank">last tutorial</a> I showed you how to use CSS-like stylesheets in your iPhone Apps. Although I did make a custom cell I didn&#8217;t really show how this is done, and I&#8217;ve decided to go into a bit more detail.</p>
<p>In this tutorial I am going to show you how to make custom table cells in your iPhone Apps using Joe Hewitt&#8217;s <a title="Three20 iPhone library on GitHub" href="http://github.com/joehewitt/three20/tree/master" target="_blank">Three20 library</a>.</p>
<p>Custom cells are very useful, they let you do things like this:</p>
<p><a href="http://mattvague.com/wordpress/wp-content/uploads/2009/06/Picture-11.png"><img class="alignnone size-full wp-image-600" title="Some Custom Cells (From the three20 catalogue App)" src="http://mattvague.com/wordpress/wp-content/uploads/2009/06/Picture-11.png" alt="Custom Cells" width="132" height="200" /></a></p>
<p>But it&#8217;s worth mentioning that i&#8217;m not going show you how to make a complete iPhone App, nor install the Three20 library in your Apps (there is already a guide on how to do this on the <a href="http://github.com/joehewitt/three20/tree/master" target="_blank">three20 github page</a>).</p>
<p>I am going to assume that you either cloned my <a href="http://github.com/mattvague/three20-iPhone-tutorials/tree/master">three20 tutorial repository</a> from github and are following along in my <a href="http://mattvague.com/three20-stylesheets-tutorial" target="_blank">Three20 stylesheets tutorial</a>, or that you already have an app using three20 with a working tableview and datasource similar to mine (there are several ways to do this, but I am going to assume you&#8217;re using my way).</p>
<p>By the way, all my Three20 tutorials are available <a href="http://github.com/mattvague/three20-iPhone-tutorials/tree/master" target="_blank">on gitHub</a>.</p>
<p><strong>So lets get started:</strong></p>
<p>First things first, There are cells, and there are fields.</p>
<ul>
<li><strong>Cells</strong> control the labels, images, interface elements, etc that are actually displayed when a table cell is rendered.</li>
<li><strong>Fields</strong> control the actual data that is fed into each label, image, interface element, etc when the table cell is rendered.</li>
</ul>
<p>But although they usually go together, you don&#8217;t always HAVE to make a new field type for every new cell type. As long as all the data that the new cell needs is provided by an existing field, you need not make another.</p>
<p>For cells like the one below with a title and subtext, the data is fed by a field which holds 2 strings: one for the title and one for the subtext.</p>
<p><a href="http://mattvague.com/wordpress/wp-content/uploads/2009/06/Picture-3.png"><img class="alignnone size-full wp-image-601" title="Some ordindary cells" src="http://mattvague.com/wordpress/wp-content/uploads/2009/06/Picture-3.png" alt="Ordinary Cells" width="132" height="200" /></a></p>
<p>The code that styles the above cell (BNSubtextTableFieldCell) looks like this:</p>
<p><a href="http://mattvague.com/wordpress/wp-content/uploads/2009/06/Picture-5.png"><img class="alignnone size-full wp-image-783" title="Code used to style basic cells with title and subtext" src="http://mattvague.com/wordpress/wp-content/uploads/2009/06/Picture-5.png" alt="Code used to style basic cells with title and subtext" width="589" height="341" /></a></p>
<p>And the field that feeds that cell looks like this (in the Three20 source code):</p>
<p><a href="http://mattvague.com/wordpress/wp-content/uploads/2009/06/Picture-7.png"><img class="alignnone size-full wp-image-802" title="Code used to feed data to basic cells with title and subtext" src="http://mattvague.com/wordpress/wp-content/uploads/2009/06/Picture-7.png" alt="aaa" width="589" height="435" /></a></p>
<h2>JUST changing a cell&#8217;s appearance.</h2>
<p>To change the colors, font sizes, etc in a particular cell, all you need to do is subclass that cell (in this case BNSubtextTableFieldCell), and change it&#8217;s label&#8217;s properties.</p>
<ol>
<li>To subclass <strong>BNSubtextTableFieldCell</strong>, make <strong>BNCell.h</strong> looks like this:
<pre name="code" class="objc">#import "Three20/Three20.h"

///////////////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////
//////   BNSubtextTableFieldCell     ////
/////////////////////////////////////////

@interface BNSubtextTableFieldCell : TTSubtextTableFieldCell {

}

@end

///////////////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////
//////   BNSubtextWithRedTitleTableFieldCell     ////
/////////////////////////////////////////////////////

@interface BNSubtextWithRedTitleTableFieldCell : BNSubtextTableFieldCell {

}

@end

///////////////////////////////////////////////////////////////////////////////////////////////////</pre>
</li>
<li>Then make <strong>BNCell.m</strong> look like this:
<pre name="code" class="objc">#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;
		_subtextLabel.font = TTSTYLEVAR(mySecondFont);
		_subtextLabel.textColor = TTSTYLEVAR(mySecondColor);
	}
}

@end

///////////////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////
//////   BNSubtextWithRedTitleTableFieldCell     ////
/////////////////////////////////////////////////////

@implementation BNSubtextWithRedTitleTableFieldCell

///////////////////////////////////////////////////////////////////////////////////////////////////

- (void)setObject:(id)object {
	if (_field != object) {
		[super setObject:object];

		_label.textColor = [UIColor redColor];
	}
}

@end

///////////////////////////////////////////////////////////////////////////////////////////////////</pre>
<p>All we did there was change the <strong>textColor</strong> property of the cell&#8217;s _label to an ugly ass red color.</li>
<li>Next we change the <strong>cellForClassObject</strong> method in <strong>RootViewDataSource.m </strong>to point to your new BNSubtextWithRedTitleTableFieldCell cell type.
<p>Make the RootViewDataSource.m look like this:</p>
<pre name="code" class="objc">#import "RootViewDataSource.h"
#import "BNCell.h"

@implementation RootViewDataSource

///////////////////////////////////////////////////////////////////////////////////////////////////
// public

+ (RootViewDataSource*)rootViewDataSource {
	RootViewDataSource* dataSource =  [[[RootViewDataSource alloc] initWithItems:
									 [NSMutableArray arrayWithObjects:
									 [[[TTSubtextTableField alloc] initWithText:@"Video" subtext:@"Now you can shoot video, edit it, and share it — all on your iPhone 3G S."] autorelease],
									 [[[TTSubtextTableField alloc] initWithText:@"3-Megapixel Camera" subtext:@"The new 3-megapixel camera takes great still photos, too, thanks to built-in autofocus."] autorelease],
									 [[[TTSubtextTableField alloc] initWithText:@"Search" subtext:@"Find what you’re looking for across your iPhone, all from one convenient place."] autorelease],
									 [[[TTSubtextTableField alloc] initWithText:@"Compass" subtext:@"With a built-in digital compass, iPhone 3G S can point the way."] autorelease],
									 [[[TTSubtextTableField alloc] initWithText:@"Cut, Copy &amp; Paste" subtext:@"Cut, copy, and paste words and photos, even between applications."] autorelease],
									 nil]] autorelease];

	return dataSource;
}

///////////////////////////////////////////////////////////////////////////////////////////////////

- (void)dealloc {
	[super dealloc];
}

///////////////////////////////////////////////////////////////////////////////////////////////////
// TTTableViewDataSource

- (Class)tableView:(UITableView*)tableView cellClassForObject:(id) object {

	if ([object isKindOfClass:[TTSubtextTableField class]]) {
		return [BNSubtextWithRedTitleTableFieldCell class];
	} else {
		return [super tableView:tableView cellClassForObject:object];
	}
}

- (void)tableView:(UITableView*)tableView prepareCell:(UITableViewCell*)cell
forRowAtIndexPath:(NSIndexPath*)indexPath {
	cell.accessoryType = UITableViewCellAccessoryNone;
}

@end</pre>
</li>
</ol>
<p><strong>You should end up with something like this when you run your app:</strong></p>
<p><a href="http://mattvague.com/wordpress/wp-content/uploads/2009/06/Picture-2.png"><img style="border: 0px initial initial;" title="Ordindary cells with red title" src="http://mattvague.com/wordpress/wp-content/uploads/2009/06/Picture-2.png" alt="Ordindary cells with red title" width="132" height="200" /></a></p>
<p><strong>Changing a cell&#8217;s appearance AND data.</strong></p>
<p>What if we want to add another piece of data to the cell like a URL? Right now the cell can only be fed a title, and subtext because that is all that the cell&#8217;s field contains (2 NSStrings).</p>
<p>What we have to do is subclass Three20&#8242;s existing TTSubtextTableField (which currently feeds both BNSubtextTableFieldCell and BNSubtextWithRedTitleTableFieldCell) to make a new field which will hold a new piece of data (a NSString for the URL we will add).</p>
<p>But before we make a new field, let&#8217;s make a new cell that subclasses our last cell with the addition of a new UILabel for the URL.</p>
<ol>
<ol>
<li>To make a new sub-classed cell, change <strong>BNCell.h</strong> to look like this:
<pre name="code" class="objc">#import "Three20/Three20.h"

///////////////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////
//////   BNSubtextTableFieldCell     ////
/////////////////////////////////////////
we
@interface BNSubtextTableFieldCell : TTSubtextTableFieldCell {

}

@end

///////////////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////
//////   BNSubtextWithRedTitleTableFieldCell     ////
/////////////////////////////////////////////////////

@interface BNSubtextWithRedTitleTableFieldCell : BNSubtextTableFieldCell {

}

@end

///////////////////////////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////
//////   BNSubtextWithRedTitleAndURLTableFieldCell     ////
///////////////////////////////////////////////////////////

@interface BNSubtextWithRedTitleAndURLTableFieldCell : BNSubtextWithRedTitleTableFieldCell {
  UILabel* _featureURLLabel;
}

@end

///////////////////////////////////////////////////////////////////////////////////////////////////</pre>
</li>
<li>And change <strong>BNCell.m</strong> to look like this:
<pre name="code" class="objc">#import "BNCell.h"
#import "BNField.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;
		_subtextLabel.font = TTSTYLEVAR(mySecondFont);
		_subtextLabel.textColor = TTSTYLEVAR(mySecondColor);
	}
}

@end

///////////////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////
//////   BNSubtextWithRedTitleTableFieldCell     ////
////////////////////////////////////t/////////////////

@implementation BNSubtextWithRedTitleTableFieldCell

///////////////////////////////////////////////////////////////////////////////////////////////////

- (void)setObject:(id)object {
	if (_field != object) {
		[super setObject:object];

		_label.textColor = [UIColor redColor];
	}
}

@end

///////////////////////////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////
//////   BNSubtextWithRedTitleAndURLTableFieldCell     ////
////////////////////////////////////t//////////////////////

@implementation BNSubtextWithRedTitleAndURLTableFieldCell

///////////////////////////////////////////////////////////////////////////////////////////////////

+ (CGFloat)tableView:(UITableView*)tableView rowHeightForItem:(id)item {
	CGFloat maxWidth = tableView.width - 20;
	BNSubtextWithRedTitleAndURLTableField* field = item;

	CGSize textSize = [field.text sizeWithFont:TTSTYLEVAR(tableSmallFont)
					   constrainedToSize:CGSizeMake(maxWidth, CGFLOAT_MAX)
					   lineBreakMode:UILineBreakModeWordWrap];
	CGSize subtextSize = [field.subtext sizeWithFont:TTSTYLEVAR(font)
						  constrainedToSize:CGSizeMake(maxWidth, CGFLOAT_MAX) lineBreakMode:UILineBreakModeWordWrap];
	CGSize featureURLSize = [field.featureURL sizeWithFont:[UIFont systemFontOfSize:12]
						  constrainedToSize:CGSizeMake(maxWidth, CGFLOAT_MAX) lineBreakMode:UILineBreakModeWordWrap];

	return 20 + textSize.height + subtextSize.height + featureURLSize.height;
}

///////////////////////////////////////////////////////////////////////////////////////////////////

- (id)initWithFrame:(CGRect)frame reuseIdentifier:(NSString*)identifier {
	if (self = [super initWithFrame:frame reuseIdentifier:identifier]) {
		_featureURLLabel = [[UILabel alloc] initWithFrame:CGRectZero];
		_featureURLLabel.font = [UIFont systemFontOfSize:11];
		_featureURLLabel.textColor = [UIColor grayColor];
		_featureURLLabel.backgroundColor = [UIColor clearColor];
		_featureURLLabel.highlightedTextColor = TTSTYLEVAR(highlightedTextColor);
		_featureURLLabel.textAlignment = UITextAlignmentLeft;
		_featureURLLabel.contentMode = UIViewContentModeTop;
		_featureURLLabel.lineBreakMode = UILineBreakModeWordWrap;
		_featureURLLabel.numberOfLines = 0;
		[self.contentView addSubview:_featureURLLabel];
	}
	return self;
}

- (void)dealloc {
	[_featureURLLabel release];
	[super dealloc];
}

///////////////////////////////////////////////////////////////////////////////////////////////////
// UIView

- (void)layoutSubviews {
	[super layoutSubviews];
	CGFloat maxWidth = self.contentView.width - 20;
	CGSize featureURLSize = [_featureURLLabel.text sizeWithFont:_featureURLLabel.font
						  constrainedToSize:CGSizeMake(maxWidth, CGFLOAT_MAX) lineBreakMode:_featureURLLabel.lineBreakMode];
	_featureURLLabel.frame = CGRectMake(10, _subtextLabel.bottom + 5, featureURLSize.width, featureURLSize.height);
}

///////////////////////////////////////////////////////////////////////////////////////////////////
// TTTableViewCell

- (void)setObject:(id)object {
	if (_field != object) {
		[super setObject:object];

		BNSubtextWithRedTitleAndURLTableField* field = object;

		_featureURLLabel.text = field.featureURL;
	}
}

@end</pre>
</li>
</ol>
</ol>
<p>Then we need to feed data into this new cell by sub-classing TTSubtextTableField.</p>
<ol>
<li><strong>Make a new file</strong> called<strong> BNField.m</strong> (check YES to &#8220;Also create BNField.h&#8221;).</li>
<li>Then make your new <strong>BNField.h</strong> file look like this:
<pre name="code" class="objc">#import "Three20/Three20.h"

///////////////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////
//////   BNSubtextWithRedTitleAndURLTableField  /////
/////////////////////////////////////////////////////

@interface BNSubtextWithRedTitleAndURLTableField : TTSubtextTableField {
	NSString *_featureURL;
}
@property(nonatomic, retain) NSString *featureURL;
- (id)initWithText:(NSString*)text subtext:(NSString*)subtext featureURL:(NSString*)featureURL;

@end

///////////////////////////////////////////////////////////////////////////////////////////////////</pre>
</li>
<li>And make your <strong>BNField.m</strong> file look like this:
<pre name="code" class="objc">#import "BNField.h"
#import "BNCell.h"

///////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////
//////   BNSubtextWithRedTitleAndURLTableField     /////
////////////////////////////////////////////////////////

@implementation BNSubtextWithRedTitleAndURLTableField

@synthesize featureURL = _featureURL;

- (id)init {
	if (self = [super init]) {
		_featureURL = nil;
	}
	return self;
}

- (id)initWithText:(NSString*)text subtext:(NSString*)subtext featureURL:(NSString*)featureURL {
	if (self = [super initWithText:text subtext:subtext]) {
		self.featureURL = featureURL;
	}
	return self;
}

- (void)dealloc {
	[_featureURL release];
	[super dealloc];
}

@end

///////////////////////////////////////////////////////////////////////////////////////////////////</pre>
</li>
</ol>
<p>Then we have to make some changes to <strong>RootViewDataSource.m</strong><br />
We will:</p>
<ul>
<li>Include BNField.h</li>
<li>Change our datasource method calls from TTSubtextTableField to BNSubtextWithRedTitleAndURLTableField and pass a URL to this new field</li>
<li>Change the cellClassForObject method to look for our new cell type (I should note that we have to change the IF statement so that our newest class is on top otherwise it won&#8217;t be found).</li>
</ul>
<ol>
<li>Make your RootViewDataSource.m look like this:
<pre name="code" class="objc">#import "RootViewDataSource.h"
#import "BNCell.h"
#import "BNField.h"

@implementation RootViewDataSource

///////////////////////////////////////////////////////////////////////////////////////////////////
// public

+ (RootViewDataSource*)rootViewDataSource {
	RootViewDataSource* dataSource =  [[[RootViewDataSource alloc] initWithItems:
									 [NSMutableArray arrayWithObjects:
									 [[[BNSubtextWithRedTitleAndURLTableField alloc] initWithText:@"Video" subtext:@"Now you can shoot video, edit it, and share it — all on your iPhone 3G S." featureURL:@"http://www.apple.com/iphone/iphone-3gs/video-recording.html"] autorelease],
									 [[[BNSubtextWithRedTitleAndURLTableField alloc] initWithText:@"3-Megapixel Camera" subtext:@"The new 3-megapixel camera takes great still photos, too, thanks to built-in autofocus." featureURL:@"http://www.apple.com/iphone/iphone-3gs/photos.html"] autorelease],
									 [[[BNSubtextWithRedTitleAndURLTableField alloc] initWithText:@"Search" subtext:@"Find what you’re looking for across your iPhone, all from one convenient place." featureURL:@"http://www.apple.com/iphone/iphone-3gs/search.html"] autorelease],
									 [[[BNSubtextWithRedTitleAndURLTableField alloc] initWithText:@"Compass" subtext:@"With a built-in digital compass, iPhone 3G S can point the way." featureURL:@"http://www.apple.com/iphone/iphone-3gs/maps-compass.html"] autorelease],
									 [[[BNSubtextWithRedTitleAndURLTableField alloc] initWithText:@"Cut, Copy &amp; Paste" subtext:@"Cut, copy, and paste words and photos, even between applications." featureURL:@"http://www.apple.com/iphone/iphone-3gs/cut-copy-paste.html"] autorelease],
									 nil]] autorelease];

	return dataSource;
}

///////////////////////////////////////////////////////////////////////////////////////////////////

- (void)dealloc {
	[super dealloc];
}

///////////////////////////////////////////////////////////////////////////////////////////////////
// TTTableViewDataSource

- (Class)tableView:(UITableView*)tableView cellClassForObject:(id) object {

	if ([object isKindOfClass:[BNSubtextWithRedTitleAndURLTableField class]]) {
		return [BNSubtextWithRedTitleAndURLTableFieldCell class];
	} else if ([object isKindOfClass:[TTSubtextTableField class]]) {
		return [BNSubtextWithRedTitleTableFieldCell class];
	} else {
		return [super tableView:tableView cellClassForObject:object];
	}
}

- (void)tableView:(UITableView*)tableView prepareCell:(UITableViewCell*)cell
forRowAtIndexPath:(NSIndexPath*)indexPath {
	cell.accessoryType = UITableViewCellAccessoryNone;
}

@end</pre>
</li>
</ol>
<p>Once you&#8217;re done changing RootViewDataSource.m&#8230;&#8230;</p>
<p><strong>Boom! Your app should look like this when launched:</strong></p>
<p><a href="http://mattvague.com/wordpress/wp-content/uploads/2009/06/Picture-6.png"><img class="alignnone size-full wp-image-832" title="Custom table cells fed by custom fields." src="http://mattvague.com/wordpress/wp-content/uploads/2009/06/Picture-6.png" alt="Custom table cells fed by custom fields." width="132" height="200" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.mattvague.com/three20-custom-cells-iphone-tutorial/feed</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Three20 Stylesheets iPhone Tutorial</title>
		<link>http://www.mattvague.com/three20-stylesheets-tutorial</link>
		<comments>http://www.mattvague.com/three20-stylesheets-tutorial#comments</comments>
		<pubDate>Sun, 14 Jun 2009 07:09:34 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Three20]]></category>
		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://mattvague.com/?p=426</guid>
		<description><![CDATA[In this tutorial, I am going to show you how to use CSS like stylesheets in your iPhone Apps.

Right now there is no built-in equivilent to CSS for building iPhone apps, but lucky for us Joe Hewitt has created a way with his Three20 iPhone Library.]]></description>
			<content:encoded><![CDATA[<p><strong>Update:</strong> This tutorial is outdated, proceed at your own risk.</p>
<p>&#8212;</p>
<p><span class="Apple-style-span" style="font-size: 20px; font-weight: bold;">Introduction to Three20 Stylesheets</span></p>
<p>In this tutorial, I am going to show you how to use CSS like stylesheets in your iPhone Apps.</p>
<p>If (like me) you&#8217;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.</p>
<p>Lucky for us <a href="http://joehewitt.com/">Joe Hewitt</a> has created a way with his <a href="http://github.com/joehewitt/three20/tree into/master">Three20</a> iPhone Library. With Three20, you can easily <strong>change something like this:</strong></p>
<p><a href="http://mattvague.com/wordpress/wp-content/uploads/2009/06/Picture-51.png"><img class="alignnone size-full wp-image-967" title="A screenshot of my sample App WITHOUT three20 stylesheets" src="http://mattvague.com/wordpress/wp-content/uploads/2009/06/Picture-51.png" alt="A screenshot of my sample App WITHOUT three20 stylesheets" width="132" height="200" /></a></p>
<p><strong>To something like this:</strong></p>
<p><a href="http://mattvague.com/wordpress/wp-content/uploads/2009/06/Picture-1.png"><img class="alignnone size-full wp-image-521" title="A screenshot of my sample App using three20 stylesheets" src="http://mattvague.com/wordpress/wp-content/uploads/2009/06/Picture-1.png" alt="A screenshot of my sample App using three20 stylesheets" width="132" height="200" /></a></p>
<p><strong>Using this stylesheet:</strong></p>
<p><a href="http://mattvague.com/wordpress/wp-content/uploads/2009/06/Picture-4.png"><img class="alignnone size-medium wp-image-523" title="The actual stylesheet in my sample app" src="http://mattvague.com/wordpress/wp-content/uploads/2009/06/Picture-4-1000x552.png" alt="The actual stylesheet in my sample app" width="300" height="160" /></a></p>
<p>Although I am going to show you some cool features of Three20, I&#8217;m NOT going to show you how to install Three20 in your Apps, nor build a complete App with Three20. Nope, today I&#8217;m only going to show you how to use Three20&#8242;s stylesheet capabilities.</p>
<p>I&#8217;m assuming a basic knowledge of Three20 and an intermediate knowledge of Cocoa and iPhone Dev. I&#8217;m also assuming you already have a UILabel or something to that you want to change the font of.</p>
<p>If you want to get your hands dirty, there is a sample app using this same code on my <a title="My Three20 iPhone Tutorials hosted on GitHub" href="http://github.com/mattvague/three20-iPhone-tutorials/tree/master" target="_blank">GitHub Three20 tutorial repository</a>.</p>
<h2>Let&#8217;s start the show</h2>
<p><strong>First things first, create your stylesheet.</strong></p>
<ol>
<li>Create a new blank file. Do this by going File &gt;&gt; New File, then clicking NSObject Subclass. Name the file &#8220;BNDefaultStylesheet&#8221; (i like sticking to Three20&#8242;s naming conventions by replacing the abbreviation TT with the abbreviation BN for &#8220;<strong>B</strong>asic <strong>N</strong>avigation&#8221;).
<p>Copy the following code into <strong>BNDefaultStylesheet.h</strong>:</p>
<pre name="code" class="objc">#import "Three20/TTStyleSheet.h"
#import "Three20/TTDefaultStyleSheet.h"

@interface BNDefaultStyleSheet : TTDefaultStyleSheet

@end</pre>
<p>Then copy the following into <strong>BNDefaultStylesheet.m</strong>:</p>
<pre name="code" class="objc">#import "BNDefaultStyleSheet.h"
#import "Three20/TTStyle.h"
#import "Three20/TTShape.h"
#import "Three20/TTURLCache.h"

///////////////////////////////////////////////////////////////////////////////////////////////////

@implementation BNDefaultStyleSheet

@end</pre>
</li>
<li><strong>Register the new stylesheet into the app delegate. </strong>Do this by making <strong>BasicNavigationAppDelegate.m</strong> look like this:
<pre name="code" class="objc">#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</pre>
</li>
<li><strong>Make your first font style. </strong>Add a new font style and color by making <strong>BNDefaultStylesheet.h</strong> look like this:
<pre name="code" class="objc">#import "Three20/TTStyleSheet.h"
#import "Three20/TTDefaultStyleSheet.h"

@interface BNDefaultStyleSheet : TTDefaultStyleSheet

@property(nonatomic,readonly) UIColor* myFirstColor;
@property(nonatomic,readonly) UIFont* myFirstFont;

@end</pre>
<p><span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, -webkit-fantasy;">And making <strong>BNDefaultStylesheet.m</strong> look like this:</span></p>
<p>&nbsp;</p>
<pre name="code" class="objc">#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</pre>
</li>
<li><strong>Use your new style. </strong>Change the font to point to the font style by making <strong>BNCell.m</strong> look like this:
<pre name="code" class="objc">#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

///////////////////////////////////////////////////////////////////////////////////////////////////</pre>
</li>
</ol>
<p>Voila! You should now have your first App using Three20 Stylesheets. Your App should now have blue labels instead of black ones like so:</p>
<p><a href="http://mattvague.com/wordpress/wp-content/uploads/2009/06/Picture-1.png"><img class="alignnone size-full wp-image-521" title="A screenshot of my sample App WITH three20 stylesheets" src="http://mattvague.com/wordpress/wp-content/uploads/2009/06/Picture-1.png" alt="A screenshot of my sample App WITH three20 stylesheets" width="132" height="200" /></a></p>
<p>I&#8217;ll be refining this tutorial in the future, but if you find any glaring omissions please point em out.</p>
<p>AND To people following my tutorials: &#8230; <strong>DON&#8217;T BE SO PROUD</strong>. Ask questions if you have em, I&#8217;m cool with helping you get this stuff working in your Apps.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mattvague.com/three20-stylesheets-tutorial/feed</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
	</channel>
</rss>

