Feb 27 2009

iPhone Development: Tab Bar Mini HowTo

Das Interface des iPhones ist in mehrere verschiedene Komponenten unterteilt. Die Tab Bar ist dabei jene Komponenten, die am unteren Rand des Displays angezeigt wird, und zwischen verschiedenen Darstellungen umschaltet.

Beim Telefon ist dies beispielswiese Favoriten, Anrufliste, Kontakte, Ziffernblock und Voicemail; bei der Uhr Weltuhr, Wecker, Stoppuhr sowie Timer.

Eine Tab Bar ist das “höchste” Navigationselement am iPhone. D.h. wenn eine Tab Bar verwendet werden soll, so sind alle anderen Ansichten dieser untergeordnet. Daher muss bei einer Applikation mit Tab Bar basierter Navigation diese Tab Bar als erstes Element implementiert werden.

Für sämtliche Applikationen am iPhone verwende ich die Window-Based Application als Vorlage. Diese generiert nur eine AppDelegate Klasse für die Anwendung sowie eine MainWindow.xib Datei, die das Interface definiert:

bild-1-new-project-template bild-2-new-project-name bild-3-initial-project

Um eine Tab Bar zu verwenden, wird zuerst die Datei MainWindow.xib im Interface Builder geöffnet und ein Tab Bar Controller in das Fenster gezogen. Das Resultat sieht wie folgt aus:

bild-4-ib-mainwindow-xib bild-5-ib-tab-bar-controller

Anschließend wird im XCode der Controller als IBOutlet hinzugefügt, d.h. die Datei TutorialTabBarAppDelegate.h wie folgt geändert:

1
2
3
4
5
6
7
8
9
10
11
#import <UIKit/UIKit.h>

@interface TutorialTabBarAppDelegate : NSObject <UIApplicationDelegate> {
    UIWindow            *window;
    UITabBarController  *tabBarController;                                      // LINE ADDED
}

@property (nonatomic, retain) IBOutlet UIWindow             *window;
@property (nonatomic, retain) IBOutlet UITabBarController   *tabBarController;  // LINE ADDED

@end

Anschließend wird der Tab Bar Controller als View der Anwendung initialisiert, d.h. die Datei TutorialTabBarAppDelegate.m wie folgt modifiziert:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#import "TutorialTabBarAppDelegate.h"

@implementation TutorialTabBarAppDelegate

@synthesize window;
@synthesize tabBarController;                                               // LINE ADDED

- (void)applicationDidFinishLaunching:(UIApplication *)application {    
    [window addSubview:[tabBarController view]];                            // LINE ADDED

    // Override point for customization after application launch
    [window makeKeyAndVisible];
}

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

@end

Anschließend geht es wieder zurück zum Interface Builder. Hier wird der Tab Bar Controller rechts angeklickt. Daraufhin erscheint ein Popup-Fenster, in dem man den Kreis neben “New Referencing Outlet” auf das Tutorial Tab Bar App Delegate Objekt dragt, wo dann wieder ein Popup mit dem Inhalt “tabBarController” erscheint. Dieser tabBarController entspricht der IBOutlet-Variablen, die wir zuvor gerade angelegt haben. Das Resultat sollte wie folgt aussehen:

bild-6-ib-referencing-outlet

Die Applikation sollte jetzt bereits laufen und eine funktionierende Tab Bar darstellen:

bild-7-tutorial-tab-bar-v1

Damit die ganze Anwendung überhaupt erst Sinn ergibt müssen für die einzelnen Tabs noch entsprechende Inhalte generiert werden. Dazu wird für jedes Tab eine eigene View angelegt.

Dazu wird im XCode eine neue Datei vom Typ UIViewController subclass angelegt, die den Namen “Tab1ViewController” erhält:

bild-8-new-uiviewcontroller-template bild-9-new-uiviewcontroller-name

Die dadurch erstellten Dateien lasse ich vorerst unangetastet. Weiterhin wird eine Interface Builder Datei für diesen Controller erstellt, d.h. eine neue Datei vom Typ “View XIB” mit dem Namen “Tab1View” zum Projekt hinzugefügt:

bild-10-new-uiview-xib-template bild-11-new-uiview-xib-name

Die Datei Tab1View.xib muss nun mit dem Interface Builder geöffnet werden. Für den “File’s Owner” wird im Identity Inspector als Class das NSObject durch Tab1ViewController ersetzt:

bild-12-tab1view-identity-inspector

Anschließend muss das “New Referencing Outlet” der View mit dem Attribut view des “File’s Owner” verbunden werden. Dazu dient wieder ein Rechtsklick auf View und ein anschließendes Draggen des Krieses auf “File’s Owner”.

Um die View in der Tutorial-Applikation auch identifizieren zu können, wird ein entsprechendes Label in die View gezogen. Das Resultat sieht im Interface Builder dann so aus:

bild-13-tab1view

Das View muss nun noch entsprechend in der Tab Bar eingebunden werden. Die Idee dies direkt im Interface Builder zu machen ist zwar naheliegend und funktioniert auch prinzipiell – zumindest solange bis man dann versucht das Programm auszuführen, dann endet es mit einer Exception. Also muss man doch wieder zum Code greifen. Daher muss die App Delegate wir folgt angepasst werden:

TutorialTabBarAppDelegate.h:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#import <UIKit/UIKit.h>

#import "Tab1ViewController.h"                                                  // LINE ADDED

@interface TutorialTabBarAppDelegate : NSObject <UIApplicationDelegate> {
    UIWindow            *window;
    UITabBarController  *tabBarController;

    Tab1ViewController  *tab1ViewController;                                    // LINE ADDED
}

@property (nonatomic, retain) IBOutlet UIWindow             *window;
@property (nonatomic, retain) IBOutlet UITabBarController   *tabBarController;

@property (nonatomic, retain) Tab1ViewController            *tab1ViewController;// LINE ADDED

@end

TutorialTabBarAppDelegate.m:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#import "TutorialTabBarAppDelegate.h"

@implementation TutorialTabBarAppDelegate

@synthesize window;
@synthesize tabBarController;

@synthesize tab1ViewController;                                             // LINE ADDED

- (void)applicationDidFinishLaunching:(UIApplication *)application {
    tab1ViewController =                                                    // LINES ADDED
        [[Tab1ViewController alloc] initWithNibName:@"Tab1View" bundle:nil];

    [[[[tabBarController viewControllers] objectAtIndex:0] view] addSubview:[tab1ViewController view]];

    [window addSubview:[tabBarController view]];

    // Override point for customization after application launch
    [window makeKeyAndVisible];
}

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

@end

Äquivalent wird ein Tab2ViewController sowie eine Tab2View angelegt sowie im AppDelegate eingebaut. Das fertige Programm sieht dann wie folgt aus:

bild-14-finished-tab-1 bild-15-finished-tab-2

Der fertige Sourcecode des Programms ist hier als Download verfügbar: TutorialTabBar (ZIP-Archiv)

Viel Erfolg beim Programmieren!


Jan 16 2009

Interessantes Interface: Zero Chance

Über touchArcade bin ich auf Zero Chance (iTMS-Link) gestoßen (es gibt schon auch viele österreichische iPhone-Entwickler), wobei mir vor allem folgender Absatz ins Auge gestochen hat:

Zero Chance is both a top-down and a 3D third-person game – the orientation of the iPhone or iPod touch determines the perspective.

Das Demo-Video in YouTube demonstriert dies durchaus ansehlich. Ich bin mir zwar noch nicht ganz sicher, wie das eigentlich implementiert wurde, aber ich finde diese Perspektiven-Änderung aufgrund der iPhone-Lage durchaus interessant: