Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

Inhaltsverzeichnis
Geleitwort
Vorwort
1 Hello iPhone
2 Die Reise nach iOS
3 Sehen und anfassen
4 Alles unter Kontrolle
5 Daten, Tabellen und Controller
6 Models, Layer, Animationen
7 Programmieren, aber sicher
8 Datenserialisierung und Internetzugriff
9 Multimedia
10 Jahrmarkt der Nützlichkeiten
Stichwort

Buch bestellen
Ihre Meinung?

Spacer
Apps programmieren für iPhone und iPad von Klaus M. Rodewig, Clemens Wagner
Das umfassende Handbuch
Buch: Apps programmieren für iPhone und iPad

Apps programmieren für iPhone und iPad
Rheinwerk Computing
1172 S., geb., mit DVD
49,90 Euro, ISBN 978-3-8362-2734-6
Pfeil 4 Alles unter Kontrolle
Pfeil 4.1 Viewcontroller, XIBs und Storyboards
Pfeil 4.1.1 Erstellung von Viewcontrollern über XIB-Dateien
Pfeil 4.1.2 Applikationsinitialisierung
Pfeil 4.1.3 Storyboards
Pfeil 4.1.4 Modale Dialoge
Pfeil 4.1.5 Pop-over
Pfeil 4.1.6 Übergänge
Pfeil 4.2 Der Navigationcontroller
Pfeil 4.2.1 Viewcontroller anzeigen und entfernen
Pfeil 4.2.2 Die Navigationsleiste
Pfeil 4.2.3 Der Zurück-Button
Pfeil 4.2.4 Gehe drei Felder zurück
Pfeil 4.2.5 Die Werkzeugleiste
Pfeil 4.3 Navigation- und Pop-over-Controller in der Praxis
Pfeil 4.3.1 Navigationcontroller anlegen
Pfeil 4.3.2 Einen Dialog für die Einstellungen gestalten
Pfeil 4.3.3 Früher war alles besser ...
Pfeil 4.3.4 Einstellungen dauerhaft speichern
Pfeil 4.3.5 Storyboard lokalisieren
Pfeil 4.3.6 Anpassung an das iPad
Pfeil 4.4 Der Splitviewcontroller
Pfeil 4.4.1 Das Splitviewcontroller-Delegate
Pfeil 4.4.2 Eine Projektvariante erstellen
Pfeil 4.4.3 Rotationsverhalten für einzelne Viewcontroller ändern
Pfeil 4.4.4 Anlegen eines Splitviewcontrollers
Pfeil 4.4.5 Autolayout-Restriktionen per Programmcode erstellen
Pfeil 4.4.6 Anzeige des Masters
Pfeil 4.5 Der Tabbarcontroller
Pfeil 4.5.1 Aufbau einer Reiternavigation
Pfeil 4.5.2 Plaketten
Pfeil 4.5.3 Für ein paar Controller mehr
Pfeil 4.6 Der Page-Viewcontroller
Pfeil 4.6.1 Einen Page-Viewcontroller erzeugen
Pfeil 4.6.2 Die Datenquelle und das Delegate
Pfeil 4.7 Eigene Container- und Subviewcontroller
Pfeil 4.7.1 Container- und Subviewcontroller
Pfeil 4.7.2 Verwaltung der Subviewcontroller
Pfeil 4.7.3 ContainerViews leicht gemacht
Pfeil 4.8 Regelbasierte Anpassung der Oberfläche
Pfeil 4.8.1 Gestaltungsregeln ...
Pfeil 4.8.2 ... und Gestaltungsmöglichkeiten

Rheinwerk Computing - Zum Seitenanfang

4.5Der TabbarcontrollerZur nächsten Überschrift

Viele Apps enthalten mehrere Viewcontroller, die untereinander keine Hierarchie haben. Es wäre also wünschenswert, sie gleichberechtigt nebeneinander liegen zu haben. Sie können natürlich einen Viewcontroller erstellen, der einen Button für jeden Viewcontroller besitzt. Wenn der Nutzer den Button drückt, zeigt die Applikation den Viewcontroller als modalen Dialog oder über einen Navigationcontroller an. Dieses Vorgehen hat allerdings für den Nutzer den Nachteil, dass er bei einem Controllerwechsel immer zuerst zu der Ansicht mit den Buttons zurückkehren muss. Ein direkter Wechsel ist so nur sehr schwer möglich.

Ein Navigationcontroller oder modale Dialoge ergeben für den Wechsel also wenig Sinn. Eine Tabbarnavigation, auch Reiternavigation genannt, ist hierfür besser geeignet. Sie verwaltet beliebig viele Viewcontroller, von denen sie jedoch immer nur einen anzeigen kann. Über die Tabbar können Sie den Viewcontroller für die Anzeige auswählen. Dabei stellt die Tabbar für jeden Viewcontroller ein beschriftetes Icon dar. In Abbildung 4.48 sehen Sie ein Beispiel für eine Tabbar. Sie gehört zum Beispielprojekt Games aus Kapitel 6, »Models, Layer, Animationen«.

Abbildung

Abbildung 4.48 Eine Tabbar mit vier Einträgen


Rheinwerk Computing - Zum Seitenanfang

4.5.1Aufbau einer ReiternavigationZur nächsten ÜberschriftZur vorigen Überschrift

Für die Erstellung einer Tabbarnavigation in einem Storyboard legen Sie zuerst einen Tabbarcontroller an, indem Sie den entsprechenden Viewcontroller auf die Arbeitsfläche ziehen. Der Interface Builder erzeugt mit dem Tabbarcontroller direkt zwei Viewcontroller an. Sie können diese Controller in Ihrer App verwenden oder bei Nichtgefallen einfach löschen.

Um andere Viewcontroller zum Tabbarcontroller hinzuzufügen, ziehen Sie eine Verbindung vom Tabbarcontroller zum Viewcontroller und wählen den Punkt view controllers im Pop-over-Menü aus. In Abbildung 4.49 sehen Sie eine Tabbarcontroller-Szene in einem Storyboard. Der Tabbarcontroller auf der Arbeitsfläche stellt am unteren Rand seine Tabbar dar. Sie können die Reihenfolge der Einträge in der Tabbar – und damit auch in der App – anpassen, indem Sie dort die Einträge mit der Maus verschieben.

Abbildung

Abbildung 4.49 Eine Tabbarcontroller-Szene in einem Storyboard

Beim Einfügen eines Viewcontrollers in einen Tabbarcontroller legt der Interface Builder automatisch ein Objekt der Klasse UITabBarItem unterhalb des Viewcontrollers an. Über den Attributinspektor dieses Elements legen Sie das Icon und die Beschriftung des Viewcontrollers in der Tabbar fest. Für das Icon können Sie jedes Bild aus dem Ressourcenordner der App benutzen; alternativ können Sie auch Bilder aus den Image-Assets auswählen.

Tabbaricons

Die Icons in der Tabbar verwenden, analog zu den Buttons in der Navigations- und Werkzeugleiste, nur die Alphamaske des Bildes für die Anzeige. Die Icons sind im unselektierten Zustand hellgrau, und im selektierten Zustand haben sie standardmäßig die Tint-Color der Tabbar. Dabei können Sie über die Höhe des Alphawertes die Intensität festlegen. Es sind also monochrome Farbstufenbilder.

Außerdem können Sie über den Tabbar-Item die Beschriftung der Plakette (beziehungsweise Badge) bestimmen. Die Plakette ist der rote Kreis mit der 3 in Abbildung 4.48. Über die Property tabBarItem der Klasse UIViewController können Sie auf den Tabbar-Item des Viewcontrollers zugreifen.

Über das Delegate des Tabbarcontrollers können Sie die Controllerauswahl beeinflussen oder sich darüber informieren lassen. Der Tabbarcontroller fragt das Delegate über die Methode tabBarController:shouldSelectViewController:, ob er den angegebenen Viewcontroller anzeigen darf. Sie können das unterbinden, indem Sie NO zurückgeben. Nach der Anzeige eines Viewcontrollers ruft der Tabbarcontroller die Delegate-Methode tabBarController:didSelectViewController: auf.

Die Tabbar

Der Tabbarcontroller verwendet einen View der Klasse UITabBar, um die Tabbar darzustellen. Sie dürfen diese Tabbar jedoch nicht über ihre Methoden manipulieren oder ihr Delegate verändern. Stattdessen sollten Sie die Methoden des Controllers verwenden.


Rheinwerk Computing - Zum Seitenanfang

4.5.2PlakettenZur nächsten ÜberschriftZur vorigen Überschrift

Viele Apps verwenden Plaketten (Badges), um auf Neuigkeiten in den Tabs hinzuweisen. Sie können den angezeigten Wert der Plakette über die Property badgeValue der Klasse UITabBarItem setzen. Anders als beim Applikationsicon können Sie der Plakette eines Tabbareintrags auch eine (sehr) kurze Zeichenkette übergeben, die sie auch klaglos anzeigt. Wenn Sie keine Plakette anzeigen möchten, müssen Sie den Wert nil verwenden. Übergeben Sie stattdessen eine leere Zeichenkette, zeigt der Tabbareintrag auch eine leere Plakette an. Listing 4.42 enthält ein Beispiel dafür, wie ein Viewcontroller einen numerischen Wert in seine eigene Plakette setzt. Dazu müssen Sie die Zahl in eine Zeichenkette umwandeln. Den Wert 0 ändern Sie jedoch in nil, um die Plakette zu löschen.

NSUInteger theBadgeValue = ...;
NSString *theValue = theBadgeValue == 0 ? nil :
[NSString stringWithFormat:@"%d", theBadgeValue];
self.tabBarItem.badgeValue = theValue;

Listing 4.42 Aktualisierung der Plakette

Das Beispielprojekt Games in Kapitel 6 verwendet die Plakette eines Tabbareintrags, um die Anzahl neuer Highscores anzuzeigen.


Rheinwerk Computing - Zum Seitenanfang

4.5.3Für ein paar Controller mehrZur vorigen Überschrift

Ein Tabbarcontroller kann beliebig viele Viewcontroller enthalten; die Tabbar kann hingegen nur maximal fünf Einträge nebeneinander anzeigen. Bei sechs und mehr Controllern verwendet der Tabbarcontroller einen zusätzlichen Navigationcontroller mit eingebettetem Tableviewcontroller. Darüber können Sie auf die restlichen Viewcontroller zugreifen. Die Tabbar verwendet in diesem Fall den Platz für den fünften Tabbareintrag zur Anzeige des Mehreintrags, der zu diesem Tableviewcontroller führt. Abbildung 4.50 stellt diese Struktur dar.

Abbildung

Abbildung 4.50 Struktur des Tabbarcontrollers

Der Tableview des Mehreintrags listet alle Tabbarelemente der Viewcontroller auf, die keinen Platz in der Tabbar gefunden haben. Wenn Sie einen Viewcontroller aus der Tabelle auswählen, zeigt ihn der Tabbarcontroller an, indem er ihn auf den Navigationcontroller schiebt.

Die Auslagerung der Einträge aus der Tabbar in den Tableview geschieht dabei vollkommen automatisch. [Anm.: Das gilt jedoch nur für die App; der Interface Builder quetscht alle Tabbareinträge nebeneinander, bis sie Sardinen in einer Dose ähneln.] Sie haben dafür also keinen zusätzlichen Aufwand. Andererseits können Sie die Anzeige des Mehreintrags nicht unterdrücken oder bei weniger als sechs Viewcontrollern erzwingen.

Anpassungsfähige Viewcontroller

Die ersten vier Views des Tabbarcontrollers bekommen eine größere Anzeigehöhe als die Views aus dem Tableview für die Mehreinträge. Da ein Navigationcontroller diese Einträge anzeigt, haben sie wegen der Navigationsleiste eine geringere Höhe. Sie sollten bei der Erstellung darauf achten, da der Tabbarcontroller eine Neuanordnung seiner Elemente erlaubt.

Die Views der eingebetteten Viewcontroller sollten sich also an die unterschiedlichen Höhen anpassen können, was Sie in der Regel durch die Anpassung der Autosizingmasken oder des Autolayouts Ihrer Views erreichen.

Der Tabbarcontroller achtet allerdings auf Navigationcontroller bei den Mehreinträgen. Wenn Sie einen Navigationcontroller aus dem Tableview des Mehreintrags aufrufen, schiebt der Tabbarcontroller den Wurzelcontroller des Navigationcontrollers auf seinen Navigationcontroller. Der Tabbarcontroller ignoriert also diesen Navigationcontroller des Tabbareintrags und verwendet stattdessen den Navigationcontroller des Mehreintrags. Dadurch kann es nicht passieren, dass Sie einen Navigationcontroller auf einen anderen schieben.

Über den Button Bearbeiten in der Navigationsleiste gelangen Sie zu einer Ansicht, mit der Sie die Einträge in der Tabbar anpassen. Diese Ansicht zeigt alle Tabbareinträge. Sie können jeden Eintrag auf die Tabbar ziehen und dadurch deren Einträge neu festlegen (siehe Abbildung 4.51).

Abbildung

Abbildung 4.51 Bearbeiten der Tabbar

Projektinformation

Den Quellcode des nachfolgenden Beispielprojekts finden Sie auf der DVD unter Code/Apps/iOS5/More und im Github-Repository zum Buch in dem Unterverzeichnis https://github.com/Cocoaneheads/iPhone/tree/Auflage_3/Apps/iOS5/More.

Der Tabbarcontroller speichert diese neue Anordnung allerdings nicht permanent ab. Das Beispielprojekt More demonstriert ein Vorgehen, wie Sie die Anordnung der Tabbareinträge in den Nutzereinstellungen speichern. Dazu weist es jedem Viewcontroller eine fortlaufende Nummer zu. Wenn Sie die Viewcontroller umordnen, verändern Sie die Reihenfolge dieser Nummern. Das Programm speichert diese Reihenfolge in den User-Defaults ab und kann beim Neustart daraus die Anordnung der Viewcontroller wiederherstellen.

Zur Ablage der Indexwerte in den Viewcontrollern verwendet die App die Property tag der Tabbareinträge. Nach dem Laden des Tabbarcontrollers aus der NIB-Datei weist sie zunächst den Tabbareinträgen die Indexwerte zu. Dazu iteriert die Methode application:didFinishLaunchingWithOptions: über die Controller. Danach kann die App die Reihenfolge der Controller wiederherstellen, was in der Methode restoreTabBar geschieht:

NSArray *theControllers = 
self.tabBarController.viewControllers;
NSUInteger theIndex = 0;

for (UIViewController *theController in theControllers) {
theController.tabBarItem.tag = theIndex++;
}
[self restoreTabBar];

Listing 4.43 Nummerierung der Tabbareinträge

Nach jeder Änderung der Tabbareinträge soll die App die neue Reihenfolge in den User-Defaults abspeichern. Das erfolgt über die Delegate-Methode tabBarController:willEndCustomizingViewControllers:changed: des Tabbarcontrollers, deren Implementierung Listing 4.44 enthält. Da Sie nur bei einer Änderung der Reihenfolge die Werte speichern müssen, überprüft die Methode den Wert des Parameters change. Über die Key-Value-Coding-Methode valueForKeyPath: erzeugt die Methode das Array mit den Viewcontroller-Positionswerten. Das Array theIndexes enthält also die Werte der Tags der Tabbarelemente in der aktuellen Reihenfolge der Tabbar. Dabei sind die Arraye-Elemente allerdings Objekte der Klasse NSNumber, da die Instanzen von NSArray keine einfachen Datentypen wie int oder NSInteger direkt speichern können.

- (void)tabBarController:(UITabBarController *)inController 
willEndCustomizingViewControllers:(NSArray *)inControllers
changed:(BOOL)inChanged {
if(inChanged) {
NSArray *theIndexes =
[inControllers valueForKeyPath:@"tabBarItem.tag"];
NSUserDefaults *theDefaults =
[NSUserDefaults standardUserDefaults];
[theDefaults setObject:theIndexes
forKey:@"tabBarItems"];
[theDefaults synchronize];
}
}

Listing 4.44 Abspeichern der Reihenfolge in den User-Defaults

Jetzt fehlt nur der Code zur Wiederherstellung der Reihenfolge in der Tabbar. Das übernimmt die Methode restoreTabBar, die Sie in Listing 4.45 sehen. Sie liest zuerst die Indexwerte aus den User-Defaults. Die Schleife durchquert die Viewcontroller in der Reihenfolge der Indexwerte aus dem Tabbarcontroller und fügt sie in ein veränderliches Array ein. Schließlich weist sie dieses Array dem Tabbarcontroller zu.

- (void)restoreTabBar { 
NSUserDefaults *theDefaults =
[NSUserDefaults standardUserDefaults];
NSArray *theIndexes =
[theDefaults arrayForKey:@"tabBarItems"];
NSArray *theViewControllers =
self.tabBarController.viewControllers;

if(theIndexes.count == theViewControllers.count) {
NSMutableArray *theControllers = [NSMutableArray
arrayWithCapacity:theIndexes.count];
for(NSNumber *theIndex in theIndexes) {
NSUInteger theValue = theIndex.unsignedIntValue;

[theControllers addObject:
[theViewControllers objectAtIndex:theValue]];
}
self.tabBarController.viewControllers =
theControllers;
}
}

Listing 4.45 Wiederherstellung der Reihenfolge in der Tabbar

Die if-Abfrage in Listing 4.45 wirkt auf den ersten Blick überflüssig; sie vermeidet jedoch zwei Probleme. Beim ersten Start existieren noch keine Indexwerte in den User-Defaults, und ohne diese Abfrage erhielte der Tabbarcontroller ein leeres Array, da die Methode den Schleifenblock deswegen nicht ausführt. Dadurch bliebe somit auch die Tabbar leer.

Ein ähnlicher Effekt kann bei einer Aktualisierung Ihrer App auftreten, bei der Sie die Tabbar erweitern oder verkürzen. Bei einer Erweiterung würden Viewcontroller herausfallen, und eine Verkürzung hätte einen Fehler mit Programmabsturz zur Folge.

In einem Storyboard müssen Sie dem Tabbarcontroller sein Delegate über den Programmcode zuweisen. Das ist relativ einfach, wenn der Tabbarcontroller der initiale Viewcontroller in dem Storyboard ist. Hier können Sie sich den Tabbarcontroller über die Property rootViewController des Fensters holen. In der More-App für das Storyboard finden Sie dazu den entsprechenden Code in der Methode application:didFinishLaunchingWithOptions:.

self.tabBarController = (UITabBarController *)
self.window.rootViewController;
self.tabBarController.delegate = self;

Listing 4.46 Delegate des Tabbarcontrollers setzen

Wenn der Tabbarcontroller nicht der initiale Controller in seinem Storyboard ist, funktioniert diese Zuweisung nicht, weil das Fenster ja auf einen anderen Rootviewcontroller verweist. Hier müssen Sie das Delegate setzen, bevor Sie den Tabbarcontroller anzeigen. Wenn Sie dafür einen Übergang verwenden, ist die Methode prepareForSegue:sender: der richtige Platz. Listing 4.47 setzt das Application-Delegate als Delegate des Tabbarcontrollers in dieser Methode.

- (void)prepareForSegue:(UIStoryboardSegue *)inSegue
sender:(id)inSender {
if([inSegue.destinationViewController
isKindOfClass:[UITabBarController class]) {
id theDelegate =
[[UIApplication sharedApplication] delegate];

[inSegue.destinationViewController
setDelegate:theDelegate];
}
}

Listing 4.47 Delegate des Tabbarcontrollers bei einem Übergang setzen



Ihr Kommentar

Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen.

>> Zum Feedback-Formular
<< zurück




Copyright © Rheinwerk Verlag GmbH, Bonn 2014
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


[Rheinwerk Computing]

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de


  Zum Katalog
Zum Katalog: Apps programmieren für iPhone und iPad






Apps programmieren für iPhone und iPad
Jetzt bestellen


 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchempfehlungen
Zum Katalog: Apps programmieren für iPhone und iPad






Apps programmieren für iPhone und iPad


Zum Katalog: Einstieg in Objective-C 2.0 und Cocoa






Einstieg in Objective-C 2.0 und Cocoa


Zum Katalog: Spieleprogrammierung mit Android Studio






Spieleprogrammierung mit Android Studio


Zum Katalog: Android 5






Android 5


Zum Katalog: iPhone und iPad-Apps entwickeln






iPhone und iPad-Apps entwickeln


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo