Mrz 18 2009

iPhone OS / SDK 3.0

iphone-3-new-1jpgNachdem gestern ja das neue iPhone OS vorgestellt wurde, habe ich mir dieses gleich einmal näher angeschaut (allerdings werde ich es nicht so schnell installieren, da die meisten der neuen Features für meine Applikationen jetzt nicht wirklich wesentlich von Bedeutung sind – ich hab zwar schon ein paar Ideen, aber das reicht glaub ich wenn ich das implementiere wenn alles andere schon fertig ist).

Bei der Übersicht der neuen Features wären mir die folgenden Dinge aufgefallen:

  • Bluetooth Kommunikation zwischen den Geräten
  • Zugriff auf über das Dock angeschlossene Hardware (ich hab die dazugehörige ExternalAccessory API aber noch nicht wirklich durchblickt)
  • CoreData (ich werd das zwar nicht so schnell verwenden, aber prinzipiell ist das ganz nett, und könnte möglicherweise das Synchen zwischen iPhone- und Desktop-Applikationen erleichtern bzw. auf einfache Weise auf beiden Seiten die gleichen Datenrepräsentation ermöglichen)
  • CoreLocation erlaut Turn-by-Turn Anweisungen (allerdings nicht in Google Maps, aber ich vermute dass damit TomTom & Co demnächst im AppStore verfügbar sein wird)
  • Push notifications (ich glaub zwar nicht das ich die so schnell brauchen werde, aber auf dieser Basis dürfte demnächst eine Meebo-Applikation erscheinen)
  • Notes Sync (ich verwende zwar mittlerweile Things, aber das ist trotzdem schon lange überfällig)

Eine detaillierte Liste an API Änderungen ist (für Developer) auch verfügbar – die ist wirklich recht lang. Die interessantesten sind dabei:

  • CoreFoundation: NSPredicate wurde hinzugefügt. Letztens habe ich mich über dessen Fehlen geärgert, weil das Filtern von UITableViews mit NSPredicate einfacher wäre als ohne. Ein entsprechendes Beispiel wird es früher oder später hier im UITableView Tutorial geben (sobald ich dieses erstellt habe).
  • GameKit ist meiner Meinung nach ein bisschen komisch benannt, weil das nicht nur für Spiele interessant ist:

    The GKPeerPickerController class provides a standard user interface to allow a user to connect their iPhone to another user’s iPhone. The user can select between local Bluetooth connections and internet connections.

  • MapKit erlaubt es Google Maps in eigene Applikationen einzubauen.
  • UIKit hat einige interessante Erweiterungen erfahren: einige Navigationselemente lassen sich nun leicht transparent schalten.
    • UITableView: reloadRowsAtIndexPaths:withRowAnimation:, reloadSectionIndexTitles, reloadSections:withRowAnimation: erlauben es bei Anpassungen an der DataSource nur die relevanten Abschnitte neu zu laden, sodass nicht mehr die ganze UITableView neu geladen werden muss.
    • UITableViewCell: hier sind einige der bisher vorhandenen (und zu verwendenden) Properties inzwischen deprecated (so ist statt .text inzwischen .textLabel und .detailTextLabel zu verwenden)

Ansonsten sind mir jetzt für Developer keine wesentlichen Änderungen aufgefallen (zumindest nicht in Bereichen mit denen ich mich inzwischen beschäftigt habe).

Ich bin mir zwar nicht ganz sicher, inwieweit man das überhaupt veröffentlichen darf, da auf der Developer-Seite steht:

iPhone SDK 3.0 and iPhone OS 3.0 beta are pre-release software and are considered Apple Confidential Information. Any information Apple collects is subject to the terms of the Apple privacy policy.


Mrz 13 2009

Nav Bar Tutorial (Version 2)

Das zweite überarbeitete Tutorial beschäftigt sich mit der NavigationBar. Dabei handelt es sich um die Navigationsleiste am oberen Bildschirmrand, mit der man beispielsweise von Detailansichten wieder zur Übersicht zurückkommt, oder beim Bearbeiten von Einträgen die beiden Buttons “Save” und “Cancel” anzeigt.

Die UINavigationBar verwendet dabei eine Art Stack auf dem UIViewController Objekte abgelegt werden. Bei der Initialisierung muss in jedem Fall ein root ViewController angegeben werden. Dies ist jene View, die am Anfang angezeigt wird.

Mit den Methoden pushViewController:animated: sowie popViewControllerAnimated: lassen sich zusätzliche UIViewController im UINavigationController einbinden, wobei die Methode pushViewController:animated: den als Parameter angegebenen UIViewController anzeigt. Zusätzlich wird automatisch ein Back-Button auf der linken Seite der NavigationBar erzeugt, welcher den Titel des vorigen ViewControllers anzeigt. Die Methode popViewControllerAnimated: entfernt den aktuellen ViewController wieder und schaltet auf die vorige Sicht zurück.

Eine View, die in einen UINavigationController eingebunden ist, besitzt die Property navigationItem, über welche sich die angezeigte UINavigationBar modifizieren lässt. So enthält die UINavigationItem Klasse die Properties backBarButtonItem, leftBarButtonItem, rightBarButtonItem sowie title. Über diese Properties lassen sich die entsprechenden Buttons bzw. der Titel der in der Navigationbar angezeigt wird modifizieren.

Genug der Theorie. Um das Ganze zu demonstrieren möchte ich eine Applikation erstellen, die drei Views enthält, zwischen denen man mit der NavigationBar umschalten kann. Die erste View soll nur einen Add und Details-Button anzeigen, über die zur zweiten View umgeschaltet werden kann. Auf der zweiten View soll es einen Zurück-Button geben, der wieder auf die erste View zurückschaltet sowie einen Edit-Button der auf die dritte View umschaltet. Die dritte View soll die beiden Buttons Cancel (zurück zur zweiten View) und Save (ebenfalls zurück zur zweiten View) enthalten.

Wie immer beginne ich mit einem neuen Projekt vom Typ iPhone OS Window-Based Application, welche ich NavBar nenne. Dementsprechend erstellt XCode eine Hauptklasse NavBarAppDelegate.m.

Zusätzlich erstelle ich die drei Klassen für die drei Views. Diese sind ebenfalls wieder vom Typ UIViewController subclass, wobei ich diese wieder First, Second und Third taufe.

Die erste View (First.m) soll den Titel First in der NavigationBar anzeigen (Zeile 9) und zusätzlich auf der rechten Seite einen Add-Button (Zeile 10). Zusätzlich wird ein Button in der View angezeigt, der den Titel Details trägt (Zeilen 12-21). Beide Buttons werden mit der Methode buttonPressed verbunden (Zeile 10 und 17). Die Methode buttonPressed initialisiert die nächste View (also Second, Zeile 25) und zeigt diese über den ViewController an (Zeile 27).

First.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
28
29
30
#import "First.h"
#import "Second.h"

@implementation First

- (void)loadView {
    [super loadView];

    self.navigationItem.title = @"First";
    self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(buttonPressed:)];

    UIView *tempView = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 480.0)];

    UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    button.frame = CGRectMake(10.0, 10.0, 300.0, 50.0);
    [button setTitle:@"Details" forState:UIControlStateNormal];
    [button addTarget:self action:@selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
    [tempView addSubview:button];

    [self setView:tempView];
    [tempView release];
}

- (void)buttonPressed:(id)sender {
    Second *second = [[[Second alloc] initWithNibName:nil bundle:nil] autorelease];

    [self.navigationController pushViewController:second animated:YES];
}

@end

Die zweite View enthält durch das laden automatisch einen Back-Button auf der rechten Seite der NavigationBar. Zusätzlich muss ein Edit-Button auf der rechten Seite hinzugefügt werden (Zeile 10) und der Titel auf Second gesetzt werden (Zeile 9). Wenn der Back-Button gedrückt wird, schaltet der NavigationController automatisch auf die vorige View zurück. Bei Benutzung des Edit-Buttons (Zeile 8 ) muss äquivalent zur vorigen View eine neue Instanz der nächsten View erzeugt und auf diese umgeschaltet werden (Zeilen 14-16).

Second.m:

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

@implementation Second

- (void)loadView {
    [super loadView];

    self.navigationItem.title = @"Second";
    self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemEdit target:self action:@selector(buttonPressed:)];
}

- (void)buttonPressed:(id)sender {
    Third *third = [[[Third alloc] initWithNibName:nil bundle:nil] autorelease];

    [self.navigationController pushViewController:third animated:YES];
}

@end

Die letzte View besitzt den Titel Third (Zeile 8 ) sowie zwei Buttons in der Navigationbar (Cancel, Zeile 9 sowie Save, Zeile 10). Beide Buttons lösen einen Rücksprung zur vorigen View aus (Zeile 14):

Third.m:

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

@implementation Third

- (void)loadView {
    [super loadView];

    self.navigationItem.title = @"Third";
    self.navigationItem.leftBarButtonItem  = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(buttonPressed:)];
    self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSave   target:self action:@selector(buttonPressed:)];
}

- (void)buttonPressed:(id)sender {
    [self.navigationController popViewControllerAnimated:YES];
}

@end

Im Hauptprogramm (NavBarAppDelegate) muss nun eine Instanz der ersten View (der Root View) erstellt werden (Zeile 11) und ein UINavigationController mit dieser initialisiert werden (Zeile 12). Anschließend wird der Navigation Controller als View der Applikation aktiviert (Zeile 14).

NavBarAppDelegate.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
#import "NavBarAppDelegate.h"
#import "First.h"

@implementation NavBarAppDelegate

@synthesize window;

UINavigationController *navController;

- (void)applicationDidFinishLaunching:(UIApplication *)application {
    First *firstView = [[First alloc] initWithNibName:nil bundle:nil];
    navController = [[UINavigationController alloc] initWithRootViewController:firstView];

    [window addSubview:[navController view]];

    [window makeKeyAndVisible];
}

- (void)dealloc {
    [window release];
    [navController release];

    [super dealloc];
}

@end

Auch hier erspare ich es mir das ganze Projekt als Source hochzuladen, da auch dieses noch recht trivial ist. Die nächsten geplanten Tutorials sind: Kombination UITabBar mit UINavigationBar, UITableView sowie Delegation. Sowie eventuell etwas über Cocoa-Memorymanagement. Mal schauen…