Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Mobile / iPhone

Beginning a Navigation-Based App

4.75/5 (10 votes)
8 Jul 2010CPOL5 min read 46.6K  
A simple tutorial on how to create a navigation-based application and transitioning between views.

Introduction

I've not been developing iPhone applications for long, but hopefully, this simple tutorial will give you a clear idea of how to go about:

  • Creating a navigation-based app
  • Creating new class objects
  • Populating a UITableView with an array of objects
  • Transitioning between views

Step 1: Create a New Project

Start up X-Code and select File > New Project > Navigation-Based Application > Choose.

1.JPG

Give the project the name 'MusicApp'.

Step 2: Creating our Objects

The next step is to create an 'Artist' class that inherits from NSObject. We will use this to create objects that can be selected by the user on the first screen of the app.

Click File > New File > Objective-C class, and select subclass of NSObject.

2.JPG

Give the class the name 'Artist' and make sure that Artist.h is checked. We now need to define the properties of this class. For this example, an artist will have a name and a biography.

Add the following code to Artist.h:

C++
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

@interface Artist : NSObject {
    NSString *name;
    NSString *biography;
}    
    @property(nonatomic,copy) NSString *name;
    @property(nonatomic,copy) NSString *biography;
    
    - (id)initWithName:(NSString*)n biography:(NSString *)bio;

@end

The line -(id)initWithName:(NSString*)n description:(NSString *)desc; is a declaration of a function that is used to initialise our Artist object. All NSObjects have an init method, but we will create our own in order to pass additional arguments to initialise the object.

Add the following code to Artist.m:

C++
#import "Artist.h"

@implementation Artist
@synthesize name,biography;

- (id)initWithName: (NSString*)n biography:(NSString*)bio {
    
    self.name = n;
    self.biography = bio;
    return self;    
}
@end

Above, we have implemented the initWithName method that takes two arguments and assigns them to our local variables just like any other constructor. The line return self; is needed to return a new instance of the object.

Step 3: Transitioning between Views

The first thing we are going to do is set the title of the first screen. This is necessary to create a back button.

Add the following code to RootViewController.m:

C++
#import "RootViewController.h"
#import "MusicAppAppDelegate.h"
#import "Artist.h"

@implementation RootViewController
@synthesize artistView;

- (void)viewDidLoad {
    [super viewDidLoad];

    self.title = @"Artists";
}

The viewDidLoad method is used to set the title of the first screen. You will notice we have added 'artistView'. This is a second ViewController which we will create later (when the user selects an artist, we display this view). The line @synthesize artistView; is used to add the getter and setter methods.

We are now going to declare an array of artist objects that can be selected on the first screen.

Add the following code to MusicAppAppDelegate.h:

C++
#import <uikit>

@interface MusicAppAppDelegate : NSObject <uiapplicationdelegate> {
    
    UIWindow *window;
    UINavigationController *navigationController;
    NSMutableArray *artists;
}

@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet 
           UINavigationController *navigationController;
@property (nonatomic, retain) NSMutableArray *artists;

After declaring the array, we now need to create our Artist objects.

Add the following code to MusicAppAppDelegate.m:

C++
#import "MusicAppAppDelegate.h"
#import "RootViewController.h"
#import "Artist.h"

@implementation MusicAppAppDelegate

@synthesize window;
@synthesize navigationController;
@synthesize artists;

#pragma mark -
#pragma mark Application lifecycle

- (void)applicationDidFinishLaunching:(UIApplication *)application {    
    
    // Override point for customization after app launch
    Artist *artist1 = [[Artist alloc] initWithName:@"Artist1" biography:@"Type bio here"];
    Artist *artist2 = [[Artist alloc] initWithName:@"Artist2" biography:@"Artist 2 biogrpahy"];
    Artist *artist3 = [[Artist alloc] initWithName:@"Artist3" biography:@"Artist 3 biography"];
    
    self.artists = [[NSMutableArray alloc] initWithObjects:artist1,artist2,artist3,nil];
    
    [window addSubview:[navigationController view]];
    [window makeKeyAndVisible];
}

The first thing to notice is that we have added @synthesize artists; at the top. This is so that other objects can access the array we have declared.

In the applicationDidFinishLaunching method, we have created three Artist objects using the constructor we wrote earlier. The line self.artists = [[NSMutableArray alloc] initWithObjects:artist1,artist2,artist3,nil]; creates a new array that contains our Artist objects and assigns it to the array we have declared. Note that nil is the final argument and is needed to end the array.

When a user selects an artist on the first screen, we want to display their biography on the second. Create a new ViewController called 'ArtistViewController' - File > New File.

3.JPG

Make sure 'With XIB for user interface' is selected. The XIB file is the interface that is presented to the user. Double click on the XIB file and the Interface Builder will load. Drag a UITextView onto the view; this will be used to display the artist's biography. Save and close the Interface Builder.

4.JPG

In ArtistViewController.h, add the following code:

C++
#import <uikit>

@interface ArtistViewController : UIViewController {
    IBOutlet UITextView *artistBio;
}

@property(nonatomic,retain) IBOutlet UITextView *artistBio;
@end

Here, we create an Interface Builder Outlet so that we can associate a property with the UITextView and display it on screen. Add the line @synthesize artistBio; to the ArtistViewController.m underneath @implementation, to create the getter and setter methods for the artistBio property.

We now need to connect the outlet to the UITextView. In order to do that, double click on the ArtistViewController.xib file again to open Interface Builder. Click on File's Owner and go to Tools > Connection Inspector. Just drag the outlet on to the UITextView, then Save and Close Interface Builder.

5.JPG

In order to transition to this view, we need to declare a variable in the initial ViewController.

Add the following code to RootViewController.h:

C++
#import "ArtistViewController.h"
@interface RootViewController : UITableViewController {
    ArtistViewController *artistView;
}

@property(nonatomic,retain)ArtistViewController *artistView;

@end

By adding the line #import "ArtistViewController.h", we can create new instances of the ArtistViewController.

Step 4: Displaying and Selecting Objects

To tell the first ViewController how many items to display, there is a method called numberOfRowsInSection. We need to set this number to be the size of the artist array that we declared earlier.

Open RootViewController.m, and add the following code:

C++
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    MusicAppAppDelegate *appDelegate = (
        MusicAppAppDelegate *)[[UIApplication sharedApplication] delegate];
    return appDelegate.artists.count;
}

The first line gives us access to the appDelegate where we declared the artist array. Then all we have to do is return the item count of the array.

Next, we need to display the artist names on the first view. Add the following code to the cellForRowAtIndexPath method:

C++
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(
   NSIndexPath *)indexPath {
    
    static NSString *CellIdentifier = @"Cell";
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = 
        [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
        reuseIdentifier:CellIdentifier] autorelease];
    }
    
    // Configure the cell.
    
    MusicAppAppDelegate *appDelegate = 
              (MusicAppAppDelegate *) [[UIApplication sharedApplication] delegate];
    Artist *artist = (Artist *)[appDelegate.artists objectAtIndex:indexPath.row];
    
    [cell setText:artist.name];

    return cell;
}

The first line we add is used to access the appDelegate again where the array is stored. We then index the artist array with the current cell index (indexPath.row) to return an Artist. The cell's Text property is then set to be the artist's name.

The last step is to determine which artist the user has selected. In the method didSelectRow, add the following code:

C++
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    // Navigation logic may go here -- for example, create and push another view controller.
    // AnotherViewController *anotherViewController = 
         //    [[AnotherViewController alloc] initWithNibName:@"AnotherView" bundle:nil];
    // [self.navigationController pushViewController:anotherViewController animated:YES];
    // [anotherViewController release];
    
    MusicAppAppDelegate *appDelegate = (
             MusicAppAppDelegate *)[[UIApplication sharedApplication] delegate];
    Artist *artist = (Artist *)[appDelegate.artists objectAtIndex:indexPath.row];
    
    if(self.artistView == nil){    
        ArtistViewController *viewController = 
                  [[ArtistViewController alloc] initWithNibName:@"ArtistViewController" 
                  bundle:[NSBundle mainBundle]];
        self.artistView = viewController;
        [viewController release];        
    }
    
    [self.navigationController pushViewController:self.artistView  animated:YES];
    self.artistView.title = [artist name];
    self.artistView.artistBio.text = [artist biography];    
}

In the same way as the previous method, we gain access to the artist array from the appDelegate and index that array with the selected cell index (indexPath.row) to return an artist. The line if(self.artistView == nil) tests to see if the ArtistViewController has been initialised; if not, a new object will be created. Finally, the ArtistViewController is pushed onto the navigationController stack, the title property and UITextView value are set, and we move to the next view.

Click Build and Go and the app will launch.

6.JPG

References

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)