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

Inhaltsverzeichnis
Geleitwort
Vorwort
1 Hello iPhone
2 Grundlagen
3 Views und Viewcontroller
4 Alles unter Kontrolle
5 Daten, Tabellen und Controller
6 Models, Layer, Animationen
7 Programmieren, aber sicher
8 Datenserialisierung und Internetzugriff
9 Jahrmarkt der Nützlichkeiten
A Sicherer Entwicklungszyklus
Stichwort

Download:
- ZIP, ca. 49,9 MB
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
Galileo Computing
1000 S., geb., mit DVD
39,90 Euro, ISBN 978-3-8362-1915-0
Pfeil 6 Models, Layer, Animationen
Pfeil 6.1 Modell und Controller
Pfeil 6.1.1 iOS Next Topmodel
Pfeil 6.1.2 View an Controller
Pfeil 6.1.3 Modell an Controller
Pfeil 6.1.4 Undo und Redo
Pfeil 6.1.5 Unit-Tests
Pfeil 6.2 Als die Views das Laufen lernten
Pfeil 6.2.1 Animationen mit Blöcken
Pfeil 6.2.2 Transitionen
Pfeil 6.2.3 Zur Animation? Bitte jeder nur einen Block!
Pfeil 6.3 Core Animation
Pfeil 6.3.1 Layer
Pfeil 6.3.2 Vordefinierte Layer-Klassen
Pfeil 6.3.3 Unser Button soll schöner werden
Pfeil 6.3.4 Spieglein, Spieglein an der Wand
Pfeil 6.3.5 Der bewegte Layer
Pfeil 6.3.6 Daumenkino
Pfeil 6.3.7 Relativitätstheorie
Pfeil 6.3.8 Der View, der Layer, seine Animation und ihr Liebhaber
Pfeil 6.3.9 Die 3. Dimension
Pfeil 6.4 Scrollviews und gekachelte Layer
Pfeil 6.4.1 Scrollen und Zoomen
Pfeil 6.4.2 Die Eventverarbeitung
Pfeil 6.4.3 Scharfe Kurven
Pfeil 6.4.4 Ganz großes Kino
Pfeil 6.4.5 PDF-Dateien anzeigen
Pfeil 6.5 Über diese Brücke musst du gehen
Pfeil 6.5.1 Toll-Free Bridging und ARC
Pfeil 6.5.2 C-Frameworks und ARC
Pfeil 6.6 Was Sie schon immer über Instruments wissen wollten, aber nie zu fragen wagten
Pfeil 6.6.1 Spiel mir das Lied vom Leak
Pfeil 6.6.2 Ich folgte einem Zombie
Pfeil 6.6.3 Time Bandits

Galileo Computing - Zum Seitenanfang

6.2 Als die Views das Laufen lerntenZur nächsten Überschrift

Für jedes Puzzleteil verwendet die App einen eigenen Imageview, wobei sie ein großes Bild in die passenden Bilder für die Teile zerschneidet. Das ist sehr praktisch, wenn Sie das Bild austauschen wollen. Sie brauchen nur zwei Bilder in jeweils der Standard- und der Retina-Auflösung in den Ressourcen auszutauschen und sie nicht noch manuell zu zerschneiden.

Dazu enthält das Programm die Kategorie UIImage(Subimage) mit zwei Methoden. Über subimageWithRect: können Sie aus einem Bild einen rechteckigen Bereich in ein neues Bild kopieren:

- (UIImage *)subimageWithRect:(CGRect)inRect {
CGImageRef theImage =
CGImageCreateWithImageInRect(self.CGImage, inRect);
UIImage *theResult = [UIImage imageWithCGImage:theImage];

CGImageRelease(theImage);
return theResult;
}

Listing 6.20 Kopieren eines rechteckigen Bereiches in ein neues Bild

Die zweite Methode, splitIntoSubimagesWithRows:columns:, zerlegt ein Bild in gleichgroße, rechteckige Bilder und liefert das Ergebnis in einem Array zurück. Das Bild enthält seine Größe als geräteunabhängige Werte. Im Puzzle liefert size also immer 300 × 300 Pixel für das Puzzlebild – egal ob es für die Standard- oder die Retina-Auflösung ist. Sie müssen also diese logische Bildgröße erst in die physikalische umrechnen, indem Sie die Breite und die Höhe mit dem Skalierungsfaktor multiplizieren. Den Faktor erhalten Sie über die Property scale der Klasse UIImage.

- (NSArray *)splitIntoSubimagesWithRows:(NSUInteger)inRows Zeilenumbruch
columns:(NSUInteger)inColumns {
CGSize theSize = self.size;
CGRect theRect = CGRectMake(0.0, 0.0, Zeilenumbruch
self.scale * theSize.width / inColumns, Zeilenumbruch
self.scale * theSize.height / inRows);
NSMutableArray *theResult = [NSMutableArray Zeilenumbruch
arrayWithCapacity:inRows * inColumns];

theSize = theRect.size;
for(NSUInteger theRow = 0; theRow < inRows; ++theRow) {
for(NSUInteger theColumn = 0; theColumn < inColumns; Zeilenumbruch
++theColumn) {
theRect.origin.x = theSize.width * theColumn;
theRect.origin.y = theSize.height * theRow;
[theResult addObject: Zeilenumbruch
[self subimageWithRect:theRect]];
}
}
return [theResult copy];
}

Listing 6.21 Aufteilen eines Bildes für das Puzzle

Bei der Aktualisierung des Puzzles brauchen Sie jeweils nur den Stein an seine neuen Positionen zu setzen. Das können Sie erreichen, indem Sie der Property frame des Views für das Puzzleteil einen entsprechenden Wert zuweisen. Um zu einem Puzzleteil den entsprechenden Subview zu finden, vertauscht die Methode die Views in der Reihenfolge. Dadurch entspricht die Position des Views im Subview-Array der Position des Puzzleteils im Array des Modells.

- (void)puzzleDidTilt:(NSNotification *)inNotification {
NSDictionary *theInfo = inNotification.userInfo;
NSUInteger theFromIndex = Zeilenumbruch
[[theInfo objectForKey:kPuzzleFromIndexKey] intValue];
NSUInteger theToIndex = Zeilenumbruch
[[theInfo objectForKey:kPuzzleToIndexKey] intValue];
UIView *thePuzzleView = self.puzzleView;
UIView *theFromView = Zeilenumbruch
[thePuzzleView.subviews objectAtIndex:theFromIndex];
UIView *theToView = Zeilenumbruch
[thePuzzleView.subviews objectAtIndex:theToIndex];

[thePuzzleView exchangeSubviewAtIndex:theFromIndex Zeilenumbruch
withSubviewAtIndex:theToIndex];
theFromView.frame = [self frameForItemAtIndex:theToIndex];
theToView.frame = [self frameForItemAtIndex:theFromIndex];
}

Listing 6.22 Aktualisierung der Puzzleteile


Galileo Computing - Zum Seitenanfang

6.2.1 Animationen mit BlöckenZur nächsten ÜberschriftZur vorigen Überschrift

Mithilfe von Blöcken können Sie anfangen, Ihre Views in Bewegung zu setzen. Dazu bietet Ihnen die Klasse UIView eine Reihe von Klassenmethoden. Die Methoden operieren nicht auf Objektebene, da Sie innerhalb einer Animation mehrere Views gleichzeitig verändern können. Die Animationen beschreiben Sie dabei über Property-Veränderungen der beteiligten Views. Sie geben dazu einfach an, welchen Wert die Property am Ende des Animationsablaufs haben soll, und den Rest erledigt Cocoa für Sie. Diese Animationsbeschreibung erfolgt innerhalb eines Blocks. Die Arbeit mit Blöcken haben Sie ja bereits in Kapitel 2, »Grundlagen«, kennengelernt. Im einfachsten Fall wollen Sie nur eine oder mehrere Eigenschaften Ihrer Views verändern und das über eine Animation visualisieren. Beispielsweise können Sie folgendermaßen einen View animiert vergrößern:

CGRect theFrame = theView.frame;
theFrame.size.width *= 2;
theFrame.size.height *= 2;
[UIView animateWithDuration:0.75 animations:^{
theView.frame = theFrame;
}];

Listing 6.23 Animierte Vergrößerung eines Views

Durch diesen Code verdoppeln Sie jeweils die Breite und Höhe des Views, und Cocoa Touch visualisiert diese Änderung, indem es den View über eine Bewegung aufzieht, die eine Dreiviertelsekunde dauert. Dabei enthält dieser Code gegenüber einer nicht animierten Version nur den Aufruf der Klassenmethode animateWithDuration:animations: und den Block zusätzlich.

Parameterlose Blockfunktionen

Wenn eine Blockfunktion keinen Parameter erwartet, können Sie die Angabe der Parameterliste auch weglassen. In Listing 6.23 können Sie deshalb die Definition des Animationsblocks von ^(void){ ... } auf ^{ ... } verkürzen.

Sie können also eine Animation durch einen Methodenaufruf und eine Zeile im Animationsblock starten. Cocoa erzeugt automatisch die notwendigen Animationen zu den Änderungen, die Sie im Animationsblock an den Views vornehmen. Auf die Abläufe im Hintergrund gehen wir Abschnitt 6.3 noch genauer ein.

In vielen Fällen möchten Sie am Ende der Animation weiteren Code ausführen. Dafür gibt es die Variante animateWithDuration:animations:completion: mit zwei Blockfunktionen als Parametern:

[UIView animateWithDuration:0.75 animations:^{
theView.frame = theFrame;
}
completion:^(BOOL inFinished) {
theView.alpha = 0.5;
}];

Listing 6.24 Animation mit Block für das Animationsende

Die Animation ruft nach ihrer Beendigung den zweiten Block auf. Dabei gibt der boolesche Parameter an, ob Cocoa Touch die Animation regulär beendet oder vor der Beendigung abgebrochen hat. In der Regel hat dieser Parameter also den Wert YES. Während auch dieser Code die Größe des Views kontinuierlich ändert, setzt er die Transparenz in einem Schritt auf 50 %, weil diese Änderung ja nicht im Animationsblock steht. Wollen Sie hingegen den View synchron zur Größenänderung ausblenden lassen, müssen Sie die Anweisung theView.alpha = 0.5; vom Completion- in den Animationsblock verschieben.

Abbrechen von Animationen

Für den Abbruch von View-Animationen gibt es keine dokumentierte Methode im UIKit. Da diese Animationen jedoch auf Core Animation basieren, können Sie auf die Animationen eines Views über seinen Layer zugreifen. Die folgende Anweisung stoppt alle laufenden Animationen des Views:

[theView.layer removeAllAnimations];

Wenn Sie die Animationen so stoppen, springt der View augenblicklich in den Endzustand. Alle animierten Propertys des Views haben also die Werte, die Sie ihnen im Animationsblock zugewiesen haben.

Sie können folgende Propertys eines Views animieren:

  • Mit den Propertys frame und bounds können Sie die Position und die Größe des Views verändern.
  • Über die Property center verschieben Sie den Mittelpunkt eines Views. Das hat nicht nur Auswirkungen auf dessen Lage, sondern auch auf die Transformation des Views.
  • Sie können einem View eine affine Transformation, das ist eine 3×3-Matrix einer bestimmten Struktur, über die Property transform zuweisen. Mit Transformationen können Sie den View beispielsweise drehen, vergrößern und verschieben.
  • Ein- und Ausblendeffekte können Sie durch eine Änderung des Wertes der Property alpha erreichen.
  • Sogar die Hintergrundfarbe des Views können Sie über die Property backgroundColor animieren.
  • Über die Property contentStretch bestimmen Sie den dehnbaren Bereich des Views.

Dehnungsübungen

Der dehnbare Bereich eines Views ist ein Rechteck, dessen Breite und Höhe der View anpassen darf (siehe Abbildung 6.14). Allerdings kann der View auch Bereiche an den Rändern anpassen (das ist durch Pfeile in der Abbildung gekennzeichnet). Für die Koordinaten geben Sie relative Werte zwischen 0 und 1 an. Für den x-Wert entspricht also 0 dem linken und 1 dem rechten Rand, und 0,5 liegt genau in der Mitte. Analog ist 0,5 die halbe und 1 die volle Breite des Views. Dadurch sind die Größenangaben unabhängig von der Größe des Views. Das Rechteck für Abbildung 6.14 hat beispielsweise folgende Werte:

theView.contentStretch = CGRectMake(0.125, 0.25, 0.625, 0.5);

Mit diesen sieben animierbaren Propertys lässt sich schon eine Menge anstellen. Beispielsweise können Sie durch die animierte Änderung des Frames oder des Alphawertes Subviews ein- und ausblenden lassen. Die Transformationsmatrix der Property transform ist eine C-Struktur namens CGAffineTransform, die Sie über diverse Funktionen erstellen und modifizieren können. Sie hat anfänglich den Wert CGAffineTransformIdentity, der die Geometrie des Views nicht verändert. Andere Matrizen lassen sich nun auf zwei Weisen erzeugen: Entweder erzeugen Sie eine neue Matrix zu vorgegebenen Werten oder Sie ändern eine vorhandene Matrix.

Abbildung

Abbildung 6.14 Dehnbare Bereiche (Pfeile) eines Views

Tabelle 6.3 Erzeugung von Transformationsmatrizen

Funktion Beschreibung

CGAffineTransformMake

Erzeugt eine Transformationsmatrix über sechs Werte: eine 2×2-Matrix und eine Verschiebung. Diese Funktion verwendet man aber nur äußerst selten.

CGAffineTransformMakeRotation

Über diese Funktion erstellen Sie eine Drehung zu einem angegebenen Winkel im Bogenmaß.

CGAffineTransformMakeScale

Erstellt eine Skalierung über zwei Werte entlang der x- und der y-Achse. Mit den Wertpaaren
(1, –1)
und (-1, 1) können Sie den View an der x- beziehungsweise y-Achse spiegeln.

CGAffineTransformMakeTranslation

Diese Transformation verschiebt den View in Richtung der angegebenen Werte.

Transformationsmatrizen

Die Grundlagen für die Transformationsmatrizen oder affinen Transformationen sind ein Teilgebiet der linearen Algebra. Da die hier vorgestellten Funktionen für die meisten Anwendungsfälle ausreichen, verzichten wir auf eine genauere Darstellung.

Allerdings gibt es bei Rotationen einen kleinen Fallstrick: Die Darstellung als Matrix erlaubt nur Drehungen im Winkelbereich von -p (-180°) bis p (180°). Winkelangaben außerhalb dieses Bereiches führen allerdings nicht zu einem Programmfehler, sondern nur zu einer unerwarteten Drehung. Wenn Sie beispielsweise die Matrix für eine Dreivierteldrehung (3p / 2) gegen den Uhrzeigersinn erzeugen, führt das zu einer Vierteldrehung im Uhrzeigersinn. Die Animation des Views nimmt also eine Abkürzung, wobei das Endergebnis allerdings gleich ist. Kontinuierliche Rotationen lassen sich so allerdings nur sehr schwer realisieren. Dafür verwenden Sie besser Core Animation, worauf Abschnitt 6.3 noch genauer eingeht.

Wenn Sie mehrere Transformationen, z. B. eine Rotation und eine Skalierung, auf einen View anwenden möchten, können Sie auch bestehende Transformationsmatrizen miteinander verknüpfen. Sie können dabei entweder jeweils eine der Operationen Verschieben (CGAffineTransformTranslate), Skalieren (CGAffineTransformScale) oder Drehen (CGAffineTransformRotate) auf eine Matrix anwenden. Alternativ können Sie auch über die Funktion CGAffineTransformConcat zwei Matrizen so miteinander verknüpfen, als hätten Sie die Transformationen nacheinander ausgeführt.

Das Memory-Spiel des Beispielprojekts Games lässt zwei gleiche Spielkarten durch eine halbe Drehung mit gleichzeitiger Verkleinerung verschwinden, wodurch ein Strudeleffekt entsteht. Dazu verknüpft es eine Rotation mit einer Skalierung (in Listing 6.25 hervorgehoben). Nach Beendigung der Animation versteckt es die beiden Views für die Karten und setzt die Transformationsmatrix wieder auf die Identität, damit die Karten bei einem erneuten Start des Spiels wieder die richtige Darstellung haben.

[UIView animateWithDuration:0.75 Zeilenumbruch
animations:^{
for(Card *theCard in theCards) {
CardView *theView = [self.memoryView.subviews Zeilenumbruch
objectAtIndex:theCard.index];

theView.transform = CGAffineTransformScale( Zeilenumbruch
CGAffineTransformMakeRotation(M_PI), Zeilenumbruch
0.1, 0.1);
}
}
completion:^(BOOL inFinished) {
for(Card *theCard in theCards) {
CardView *theView = [self.memoryView.subviews Zeilenumbruch
objectAtIndex:theCard.index];

theView.hidden = theCard.solved;
theView.transform = CGAffineTransformIdentity;
}
}];

Listing 6.25 Verknüpfung von zwei Transformationen

Während der Animationsausführung ist die Verarbeitung von Touch-Events der animierten Views unterbrochen, sodass sie keine Eingaben empfangen können. In vielen Fällen ist das auch nicht notwendig. Es gibt jedoch noch eine weitere Animationsmethode, und zwar animateWithDuration:delay:options:animations:completion:, mit der Sie unter anderem dieses Verhalten beeinflussen können. Dazu besitzt diese Methode den Parameter options. Außerdem können Sie über den Parameter delay den Ausführungsbeginn der Animation verzögern.

Der Wert des Optionsparameters ist eine Bitmenge, die Sie aus mehreren Konstanten zusammensetzen können, die einen booleschen Wert darstellen. Wenn Sie mehrere Eigenschaften über die Optionen setzen wollen, müssen Sie die entsprechenden Konstanten über den Operator für das bitweise Oder | verknüpfen.

Die Touchverarbeitung während der Animation lässt sich über die Konstante UIViewAnimationOptionAllowUserInteraction aktivieren. Über Viewanimationen können Sie Ihre Views allerdings auch kontinuierlich animieren. Dazu müssen Sie nur den Schalter UIViewAnimationOptionRepeat setzen, dann setzt die Animation am Ende der Bewegung den View wieder auf den Ursprungszustand zurück und beginnt von vorne. Dabei gibt dann der Parameter duration die Länge einer Wiederholung an, und die gesamte Animation läuft so lange, bis Sie sie explizit stoppen. Diese dauerhaften Animationen sollen häufig auch den Rückweg, also den Übergang vom End- zum Anfangszustand, animieren. Mit dem Schalter UIViewAnimationOptionAutoreverse können Sie dieses Verhalten einschalten.

Über den Optionsparameter können Sie auch den Geschwindigkeitsverlauf in der Animation steuern. Tabelle 6.4 listet die vier dafür möglichen Konstanten mit einer Beschreibung ihres Geschwindigkeitsverlaufs auf:

Tabelle 6.4 Geschwindigkeitsverläufe in der Animation

UIViewAnimationOptionCurve... Die Animation ...

...EaseInOut

beschleunigt am Anfang und bremst am Ende ab.

...EaseIn

beschleunigt am Anfang und läuft dann bis zum Ende mit einer konstanten Geschwindigkeit.

...EaseOut

startet mit einer konstanten Geschwindigkeit und verlangsamt sich am Ende.

...Linear

hat über den gesamten Verlauf die gleiche Geschwindigkeit.

Projektinformation

Das Beispielprojekt Animation, das Sie auf der beiliegenden DVD unter Code/Apps/Animation oder im Github-Repository zum Buch im Unterverzeichnis https://github.com/Cocoaneheads/iPhone/tree/Auflage_2/Apps/Animation finden, vermittelt einen Eindruck von den verschiedenen Animationsverläufen. Sie können dort über ein Segmented Control die Animationskurve auswählen und eine Animation starten.

Durch wiederholte Animationen können Sie sehr leicht die Wackelanimation erzeugen, die Sie sicherlich aus dem Springboard des iPhones kennen, wenn Sie dessen Apps bearbeiten möchten. [Falls Sie sie nicht kennen: Drücken Sie einfach ein Icon im Springboard so lange, bis alle Icons zu wackeln anfangen.] Diese Animation ist einfach eine schnelle Hin- und Zurückdrehung des Views um einen kleinen Winkel, für die Sie die Repeat- und Autoreverse-Option einschalten müssen. Außerdem sollten Sie die Ease-In-Ease-Out-Animationskurve verwenden, damit die Bewegung nicht zu abgehackt aussieht.

Damit die Animation außerdem gleichmäßig zu beiden Seiten dreht, müssen Sie den View vor der Animation mit dem negativen Winkel in die Gegenrichtung drehen, was Sie nach der Beendigung allerdings wieder zurücknehmen. Den kompletten Code für diese Animation sehen Sie in Listing 6.26:

CGFloat theAngle = 2.5 * M_PI / 180;

theView.transform = CGAffineTransformMakeRotation(-theAngle);
[UIView animateWithDuration:0.05 Zeilenumbruch
delay:0.0
options:UIViewAnimationOptionRepeat | Zeilenumbruch
UIViewAnimationOptionAutoreverse | Zeilenumbruch
UIViewAnimationOptionCurveEaseInOut
animations:^{
theView.transform = Zeilenumbruch
CGAffineTransformMakeRotation(theAngle);
}
completion:^(BOOL inFinished) {
theView.transform = CGAffineTransformIdentity;
}];

Listing 6.26 Wackelanimation wie beim Bearbeiten des Springboards

Animationen ohne Blockfunktionen

Blockfunktionen hat Apple erst mit iOS 4 eingeführt. Trotzdem können Sie auch in älteren iOS-Versionen Animationen einbinden, die Sie über Aufrufe der Klassenmethoden beginAnimations:context: und commitAnimations einschließen. Mit weiteren Klassenmethoden können Sie zwischen diesen Methodenaufrufen die Animationsoptionen setzen. Die Animation aus Listing 6.23 sieht ohne Blockfunktionen beispielsweise so aus:

CGRect theFrame = theView.frame;
theFrame.size.width *= 2;
theFrame.size.height *= 2;
[UIView beginAnimations:@"resize" context:NULL];
[UIView setAnimationDuration:0.75];
theView.frame = theFrame;
[UIView commitAnimations];

Der erste Parameter der Methode beginAnimations:context: gibt den Namen der Animation an. Sie können hier auch nil verwenden. Unter diesem Namen speichert Cocoa Touch die Animation im Layer. Darauf geht Abschnitt 6.3 noch genauer ein. Im Context-Parameter können Sie der Animation beliebige Daten mitgeben, die sie an Ihre Delegate-Methoden weitergibt.

Apple hat dieses Verfahren der Animationserzeugung allerdings mit iOS 4 als veraltet markiert, und Sie sollten lieber die Klassenmethoden mit den Blockfunktionen verwenden.


Galileo Computing - Zum Seitenanfang

6.2.2 TransitionenZur nächsten ÜberschriftZur vorigen Überschrift

Mit den vorgestellten Animationen können Sie das Aussehen eines oder mehrerer Views gleichzeitig ändern. Für das Memory-Spiel aus dem Beispielprojekt Games soll eine Animation das Umdrehen der Karten simulieren. Das können Sie mit Viewtransitionen erreichen.

Transitionen sind Animationen zum gleichzeitigen Ein- und Ausblenden von Views. Die Animation verbindet dabei das Erscheinen und das Verschwinden der Views zu einem Effekt. Es gibt folgende Transitionen:

Tabelle 6.5 Transitionstypen

UIViewAnimationOptionTransition... Die Animation ...

...None

Kein Animationseffekt. Das ist der
Standardwert.

...FlipFromLeft

dreht die Views um deren vertikale Achse um 180° – die linke Seite nach vorne und die rechte nach hinten.

...FlipFromRight

dreht die Views um deren vertikale Achse um 180° – die rechte Seite nach vorne und die linke nach hinten.

...FlipFromTop

dreht die Views um deren horizontale Achse um 180°; dabei bewegt sich die obere Kante nach vorne und die untere nach hinten (erst ab iOS 5.0).

...FlipFromBottom

dreht die Views um deren horizontale Achse um 180°; dabei bewegt sich die obere Kante nach vorne und die untere nach hinten (erst ab iOS 5.0).

...CurlUp

blättert den auszublendenden View wie ein Kalenderblatt nach oben weg.

...CurlDown

blättert den einzublendenden View von oben ein.

...CrossDissolve

blendet den alten View aus und den neuen View durch einen Überblendeffekt ein (erst ab iOS 5).

Sie können eine Transition über die Klassenmethode transitionWithView:duration:options:animations:completion: von UIView starten. Dabei geben Sie im ersten Parameter den View an, dessen Subviews Sie in die Transition einbeziehen möchten. Die Transition animiert alle Views, die Sie anzeigen, verstecken, zum View hinzufügen oder aus ihm entfernen. Die anderen Parameter verhalten sich genau wie bei den bereits vorgestellten Animationsmethoden.

Die Flipanimationen eignen sich hervorragend, um das Umdrehen der Karten im Memory-Spiel der Beispielapplikation zu animieren. Eine Karte im Memory besteht aus drei Views. Der äußere View der Klasse CardView dient als Container, der jeweils einen View für die Vorder- und Rückseite der Karte enthält. Die Vorderseite zeigt ein farbiges Vieleck, während die Rückseite ein einheitliches Punktmuster anzeigt. Von diesen beiden Views ist pro Karte allerdings immer nur einer sichtbar. Das Umdrehen einer Karte vertauscht einfach die Sichtbarkeit der beiden Karten; dabei steuern Sie die Transitionen der Karten über die Methode showFrontSide:withAnimationCompletion:.

- (FrontView *)frontView {
return self.subviews.lastObject;
}

- (BOOL)showsFrontSide {
return !self.frontView.hidden;
}

- (void)setShowsFrontSide:(BOOL)inShowFront {
[[self.subviews objectAtIndex:0] setHidden:inShowFront];
self.frontView.hidden = !inShowingFront;
}

- (void)showFrontSide:(BOOL)inShow withAnimationCompletion: Zeilenumbruch
(void (^)(BOOL inFinished))inCompletion {
UIViewAnimationOptions theTransition = inShow ? Zeilenumbruch
UIViewAnimationOptionTransitionFlipFromLeft : Zeilenumbruch
UIViewAnimationOptionTransitionFlipFromRight;
[UIView transitionWithView:self Zeilenumbruch
duration:0.75 options:theTransition | Zeilenumbruch
UIViewAnimationOptionAllowUserInteraction
animations:^{
self.showsFrontSide = inShow;
}
completion:inCompletion];
}

Listing 6.27 Umdrehen der Memory-Karten über eine Transsition

Der Animationsblock verändert die Property hidden der beiden Seiten der Karte, sodass sie jeweils nur einen View zeigt. Die Transition erzeugt daraus eine Animation, die wie ein Umdrehen der Karten aussieht. Für das Anzeigen und Verstecken der Vorderseite verwendet die Methode dabei die entgegengesetzten Transitionen.

Animierbare Properties

In Listing 6.27 sieht es so aus, als hätte die Klasse CardView mit der Property showsFrontSide eine neue animierbare Property. Tatsächlich ändert die Methode setShowsFrontSide: jedoch nur die Property hidden der Views.

Diese Property ist zwar auch nicht für gewöhnliche Animationen vorgesehen, Transitionen lassen sich allerdings darüber auslösen.

Über Core Animation können Sie auch animierbare Propertys in Ihren Viewklassen implementieren.

Wenn Sie in einer Transition auch noch Views animieren wollen, können Sie dazu die Option UIViewAnimationOptionAllowAnimatedContent setzen. Dann setzt Cocoa Touch alle Änderungen an Views im Animationsblock der Transition auch in Animationen um.


Galileo Computing - Zum Seitenanfang

6.2.3 Zur Animation? Bitte jeder nur einen Block!Zur vorigen Überschrift

Wenn Sie mehrere Animationen hintereinander ausführen wollen, reicht dafür das Hintereinanderschreiben mehrerer Animationsanweisungen nicht aus. Die Animationen laufen dann trotzdem gleichzeitig ab. Das liegt einerseits daran, dass Cocoa Touch die Animationen auch aus der Runloop heraus startet. Andererseits warten die Animationsmethoden auch nicht auf den Ablauf der Animationen.

Bei Animationen können Sie dafür allerdings den Parameter delay verwenden. Wenn Sie ihn bei der zweiten Animation auf die Dauer der ersten Animation setzen, startet die zweite nach dem Ende der ersten.

Listing 6.28 enthält dazu ein Beispiel für drei aufeinanderfolgende Animationen. Es startet die erste ohne Verzögerung mit einer Dauer von einer Dreiviertelsekunde. Entsprechend startet der Code die zweite Animation mit einer Verzögerung von 750 Millisekunden. Die dritte Animation bekommt hingegen eine Verzögerung von 1250 Millisekunden, die sich aus der Summe der Dauern der ersten beiden Animationen errechnet.

[UIView animateWithDuration:0.75 animations:^{
// erste Animationsphase konfigurieren
}];
[UIView animateWithDuration:0.5 delay:0.75 options:0 Zeilenumbruch
animations:^{
// zweite Animationsphase konfigurieren
}
completions:NULL];
[UIView animateWithDuration:0.25 delay:1.25 options:0 Zeilenumbruch
animations:^{
// dritte Animationsphase konfigurieren
}
completions:NULL];

Listing 6.28 Starten von aufeinanderfolgenden Animationen

Bei Transitionen können Sie keine Verzögerung angeben. Hier können Sie jedoch den Completionblock nutzen. In diesem Block können Sie jeweils die anschließende Transition starten, sodass Sie auch hier eine sequenzielle Ausführung der Transitionen erhalten.

Das Memory-Spiel des Beispielprojekts besitzt einen Hilfeknopf, mit dem Sie die verdeckten Karten der Reihe nach kurz aufdecken können. Dazu besitzt die Klasse MemoryViewController die rekursive Methode showCardView:atIndex:, die den Inhalt der verdeckten Karten nacheinander kurz anzeigt.

- (void)showCardView:(BOOL)inShow atIndex:(NSUInteger)inIndex {
NSArray *theViews = self.memoryView.subviews;
UIViewAnimationOptions theOptions = inShow ?
UIViewAnimationOptionTransitionCurlUp :
UIViewAnimationOptionTransitionCurlDown;

if(inIndex < theViews.count) {
Card *theCard =
[self.memory.cards objectAtIndex:inIndex];
CardView *theView = [theViews objectAtIndex:inIndex];

[UIView transitionWithView:theView duration:0.25
options:theOptions
animations:^{
theView.showsFrontSide =
inShow || theCard.showsFrontSide;
}
completion:^(BOOL inFinished) {
[self showCardView:inShow atIndex:inIndex + 1];
if(inIndex == 0 && inShow) {
[self showCardView:NO atIndex:0];
}
}];
}
}

Listing 6.29 Animierte Hilfe des Memory-Spiels

Der erste Parameter gibt an, ob die Methode die Karte an der Indexposition zeigen oder verdecken soll. Das Auf- und Zudecken der Karte geschieht dabei auch über die Property showsFrontSide und eine CurlUp- beziehungsweise CurlDown-Transition. Der Completionblock der Transition startet dabei jeweils die Transition der nächsten Karte, sodass dadurch eine Kette von Transitionen entsteht. Außerdem startet der Completionblock für die erste Karte noch eine zweite Transitionskette zum Verdecken der Karten. Dazu verwendet er ebenfalls die Methode showCardView:atIndex:, diesmal allerdings mit dem Wert NO für den ersten Parameter, um die Karten zu verdecken.



Ihr Kommentar

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







<< zurück
  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: Einstieg in Objective-C 2.0 und Cocoa





 Einstieg in
 Objective-C 2.0
 und Cocoa


Zum Katalog: Apps entwickeln für iPhone und iPad - Videotraining






 Apps entwickeln für
 iPhone und iPad -
 Videotraining


Zum Katalog: Apps mit HTML5 und CSS3






 Apps mit HTML5
 und CSS3


Zum Katalog: iPhone- und iPad-Apps entwickeln






 iPhone- und
 iPad-Apps entwickeln


Zum Katalog: Android 4






 Android 4


Zum Katalog: Android-Apps entwickeln - Videotraining






 Android-Apps
 entwickeln -
 Videotraining


Zum Katalog: Windows Store Apps mit XAML und C#






 Windows Store Apps
 mit XAML und C#


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo





Copyright © Galileo Press 2013
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.


[Galileo Computing]

Galileo Press, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, info@galileo-press.de