2010-07-01 2 views
6

Ich möchte zwischen zwei Zuständen einer Ansicht animieren. Sagen wir zum Beispiel, ich habe eine Ansicht mit einem Label, und wenn ich den Text des Labels ändere, rendert eine Animation diese Änderung als Umblättern.Animiere zwischen zwei Zuständen einer Ansicht, benutze benutzerdefinierte Animation

Jetzt können Sie natürlich dies mit einem [UIView setAnimationTransition:forView:cache:]:

- (IBAction)nextPage { 
    [UIView beginAnimation:nil context:nil]; 
    [UIView setAnimationDuration:1]; 
    [UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:pageView cache:NO]; 
    label.text = @"page 2"; 
    [UIView commitAnimations]; 
} 

- (IBAction)previousPage { 
    [UIView beginAnimation:nil context:nil]; 
    [UIView setAnimationDuration:1]; 
    [UIView setAnimationTransition:UIViewAnimationTransitionCurlDown forView:pageView cache:NO]; 
    label.text = @"page 1"; 
    [UIView commitAnimations]; 
} 

... aber dann können Sie nicht Ihre eigene benutzerdefinierte Animation verwenden, können Sie den eingebauten in Animationen stecken (sie sind schön, aber Sie sind nicht auf meine Bedürfnisse zugeschnitten.

So ist die andere Option ist eine CAAnimation auf die Ebenenansicht hinzuzufügen:

- (IBAction)nextPage { 
    CAAnimation *animation = [self animationWithDuration:1 forward:NO]; 
    [pageView.layer addAnimation:animation forKey:@"pageTransition"]; 
    label.text = @"page 2"; 
} 

- (IBAction)previousPage { 
    CAAnimation *animation = [self animationWithDuration:1 forward:YES]; 
    [pageView.layer addAnimation:animation forKey:@"pageTransition"]; 
    label.text = @"page 1"; 
} 

Dann sind Sie frei zu setzen, was Animation Core Animation ermöglicht es Ihnen, zu tun. Das funktioniert gut, wenn ich eine CATransition Animation definiere, zum Beispiel eine kCATransitionReveal: Eine Ansicht in dem Zustand "Seite 2" erscheint unter der Ansicht in dem "Seite 1" -Zustand, wenn sie herausrutscht.

- (CAAnimation *)animationWithDuration:(float)duration forward:(BOOL)forward { 
    CATransition *animation = [CATransition animation]; 
    [animation setType:kCATransitionReveal]; 
    [animation setSubtype:forward?kCATransitionFromLeft:kCATransitionFromRight]; 
    [animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]]; 

    animation.duration = duration; 
    return animation; 
} 

Aber wenn ich die Animation definieren beispielsweise ein CABasicAnimation, nur einen Zustand der Ansicht zu sein, ist sichtbar.

- (CAAnimation *)animationWithDuration:(float)duration forward:(BOOL)forward { 
    CATransform3D transform = CATransform3DIdentity; 
    transform.m34 = 1.0/-1000; 
    transform = CATransform3DRotate(transform, M_PI, 0.0f, 1.0f, 0.0f); 
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform"]; 
    if(forward) { 
     animation.fromValue = [NSValue valueWithCATransform3D:transform]; 
    } else { 
     animation.toValue = [NSValue valueWithCATransform3D:transform]; 
    } 

    animation.duration = duration; 
    return animation; 
} 

Stattdessen mag ich die Ansicht in dem „Seite 1“ Zustand bis zum Ende der Animation sichtbar bleiben, während die Ansicht in dem „Seite 2“ Zustand in dem Rahmen kommt, genau so, wie es mit einem verhält Übergangsanimation.

Natürlich könnte ich immer mit der Duplizierung der Ansicht Verwirrung und eine als Geschwister-Ansicht erscheinen, während ich animiere die vorderste und entfernen Sie es aus Superview nach Abschluss ... aber es muss eine viel direktere Weg zu erreichen dieser ziemlich einfache Animationseffekt, ohne die Ansichten zu stören.

Wahrscheinlich etwas, um die Schicht zu erzählen, aber dann weiß ich nicht, was, und das ist, wo ich brauche Ihre Hilfe, Jungs :)

Dank!

Antwort

0

Nun, Sie können einen Layer erstellen, den Inhalt auf ein Bild setzen, das den Endzustand Ihrer Ansicht darstellt, und dann die Animation auf diesen Layer anwenden. Wenn die Animation beendet ist, können Sie die Ebene entfernen und den Ansichtszustand wechseln.

Ich denke, das wird besser funktionieren als die ganze Ansicht zu Instanziieren.

1

Kürzlich habe ich einen benutzerdefinierten Folie Übergang zwischen Teilansichten in einem Controller. Mein Ansatz bestand darin, eine Bitmap des View-Outs und des View-Ins zu erstellen, sie zu einer Ansicht hinzuzufügen und diese Ansicht zu animieren. Am Ende können Sie einfach die Übergangsansicht entfernen und den View-In anzeigen. Hier ist ein Ausschnitt der Übergang Methode:

-(void) transitionToView:(UIView *)viewIn lastView:(UIView *)viewOut slideRight:(BOOL)isRight { 
UIGraphicsBeginImageContext(viewOut.frame.size); 

UIImageView *bitmapOut = [[UIImageView alloc] initWithFrame: viewOut.frame]; 

[viewOut.layer renderInContext:UIGraphicsGetCurrentContext()]; 
UIImage *viewOutImage = UIGraphicsGetImageFromCurrentImageContext(); 
UIGraphicsEndImageContext(); 
bitmapOut.image = viewOutImage; 

UIImageView *bitmapIn = [[UIImageView alloc] initWithFrame: viewIn.frame ]; 
bitmapIn.frame = CGRectMake(isRight ? 320 : -320, bitmapIn.frame.origin.y, bitmapIn.frame.size.width, bitmapIn.frame.size.height); 
UIGraphicsBeginImageContext(viewIn.frame.size); 

[viewIn.layer renderInContext:UIGraphicsGetCurrentContext()]; 
UIImage *viewInImage = UIGraphicsGetImageFromCurrentImageContext(); 
UIGraphicsEndImageContext(); 

bitmapIn.image = viewInImage; 

[self.view addSubview:transitionContainer]; 

[transitionContainer addSubview:bitmapIn]; 
[transitionContainer addSubview:bitmapOut]; 

[self removeAllViews]; 

[UIView beginAnimations:nil context:nil]; 
[UIView setAnimationDuration:0.5f]; 
[UIView setAnimationDelegate:self]; 
[UIView setAnimationDidStopSelector:@selector(swapViewsAtEndOfTransition:)]; 
transitionContainer.frame = CGRectMake(isRight ? -320 : 320, 0, 640, 411); 
[UIView commitAnimations]; 

[bitmapOut release]; bitmapOut = nil; 
[bitmapIn release]; bitmapIn = nil;} 

Dann wird in der swapViewsAtEndOfTransition Selektor können Sie die Ansichten entsprechend aktualisieren.

0

Jahre sind vergangen, aber ich denke, ich habe eine Lösung für Sie gefunden. Verwenden Sie einfach kCATransitionPush anstelle von kCATransitionReveal. So:

- (CAAnimation *)animationWithDuration:(float)duration forward:(BOOL)forward { 
    CATransition *animation = [CATransition animation]; 
    [animation setType:kCATransitionPush]; 
    [animation setSubtype:forward?kCATransitionFromLeft:kCATransitionFromRight]; 
    [animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]]; 

    animation.duration = duration; 
    return animation; 
} 
Verwandte Themen