Three20 Tutorial for iOS

A Three20 tutorial for iOS introducing the Three20 library for iOS – an open source library of handy controls. By Ray Wenderlich.

Leave a rating/review
Save for later
Share
You are currently viewing page 2 of 2 of this article. Click here to view the first page.

Drilling Down to a Detail View

Now let's make it so you can tap a character to drill-down into a detail view for that character. We'll begin by making the detail view itself.

Then, right click on Classes and select Add\New File, and select Cocoa Touch Class\Objective-C class\Subclass of NSObject, and name the new file CharacterDetailController.m (and make sure "Also create CharacterDetailController.h" is checked), and click "Finish". Then replace the contents of CharacterDetailController.h with the following:

#import <Three20/Three20.h>

@interface CharacterDetailController : TTTableViewController {

}

@end

So far, exactly the same as we did for the CharacterListController - we create a subclass of TTTableViewController. Now replace the contents of CharcterDetailController.m with the following:

#import "CharacterDetailController.h"
#import "CharacterData.h"
#import "Character.h"

@implementation CharacterDetailController

- (id)initWithCharacterIndex:(int)characterIndex {
    
    if (self = [super init]) {
        
        self.tableViewStyle = UITableViewStyleGrouped;
        
        TTListDataSource *dataSource = 
            [[[TTListDataSource alloc] init] autorelease];
        
        NSMutableArray *characters = 
            [[CharacterData sharedCharacterData] characters];
        Character * character = 
            (Character *) [characters objectAtIndex:characterIndex];
        
        self.title = character.name;
        
        [dataSource.items addObject:[TTTableCaptionItem 
                                     itemWithText:character.name
                                     caption:@"Name"
                                     URL:@""]];        
        [dataSource.items addObject:[TTTableCaptionItem 
                                     itemWithText:
            [NSString stringWithFormat:@"%d", character.level]
                                     caption:@"Level"
                                     URL:@""]];        
        [dataSource.items addObject:[TTTableCaptionItem 
                                     itemWithText:
            [NSString stringWithFormat:@"%d", character.xp]
                                     caption:@"Exp"
                                     URL:@""]];        
        [dataSource.items addObject:[TTTableCaptionItem 
                                     itemWithText:character.rpgClassName
                                     caption:@"Class"
                                     URL:
            [NSString stringWithFormat:@"", characterIndex]]];
        
        self.dataSource = dataSource;
        
    }
    return self;
    
}

@end

A few differences this time. First, instead of creating a plain old init method, we have it take an argument that represents the index of the character to load.

Then, we create table items for each part of the character. We use a different Three20 table cell this time - a TTTableCaption item, which sets up a caption on the left and some text on the right, and fill in each item with one part of the character.

To link this view controller in to the rest of the app, we first need to define a URL scheme for this view controller. Go back to RPGCharsAppDelegate.m and add the following import to the top of the file:

#import "CharacterDetailController.h"

Then add the following line right underneath the line where we added the characterList mapping:

[map from:@"tt://character/(initWithCharacterIndex:)" 
    toSharedViewController:[CharacterDetailController class]];    

This code says that whenever we come across a URL that begins with "tt://character/", load up CharacterDetailController and call the initWithCharacterIndex method with the parameter of whatever come after the "tt://character/" portion of the URL.

So for example, if we tried to open the URL "tt:/character/1", it would call initWithCharacterIndex:1.

Update: Jeff from the comments section has pointed out that when constructing URLs (especially with string parameters), you have to be wary of using slashes in the URL, as Three20 may parse them as parameters. See his comment for more details to avoid this gotcha, or to see how to use a URL to call a function with more than one parameter!

Ok back to code! Now all we have to do is fill in those URL values in CharacterListController.m that we had left blank earlier. Replace the URL:@"" code with the following:

URL:[NSString stringWithFormat:@"tt://character/%d", i]

Compile and run the app, and if all goes well you should be able to dig down into the character details as well!

Screenshot of character details

Where To Go From Here?

Here's a sample project with all of the code that we've developed in the above tutorial. Note that for it to work, the three20 project needs to be a sibling folder to the RPGChars folder, and named "Three20".

Now that you've gotten a taste of Three20, feel free to experiment with some of the other goodies that Three20 has to offer! The best place to start is by loading the TTCatalog sample project that comes with Three20 - it does a great job of demonstrating the
various components that are available to you.

Have you used Three20 in any of your projects, or are you planning to use it? If so, what have you used it for (or what are you going to use it for)?