2010-07-01 4 views
6

Je voudrais animer entre deux états d'une vue. Dites, par exemple, j'ai une vue avec une étiquette et quand je change le texte de l'étiquette une animation rend ce changement comme un retournement de page.Animer entre deux états d'une vue, en utilisant une animation personnalisée

Maintenant, vous pouvez bien sûr faire cela avec un [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]; 
} 

... mais vous ne pouvez pas utiliser votre propre animation personnalisée, vous êtes coincé aux animations intégrées (ils sont gentils mais ils ne sont pas adaptés à mes besoins).

donc l'autre option est d'ajouter une CAAnimation à la couche de la vue:

- (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"; 
} 

Ensuite, vous êtes libre de définir ce que l'animation Core Animation vous permet de le faire. Cela fonctionne bien si je définis une animation CATransition, par exemple un kCATransitionReveal: une vue à l'état "page 2" apparaît sous la vue dans l'état "page 1" lorsqu'elle disparaît.

- (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; 
} 

Mais quand je l'animation à définir par exemple être un CABasicAnimation, un seul état de la vue est visible.

- (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; 
} 

Au lieu de cela, je voudrais la vue dans l'état « page 1 » de rester visible jusqu'à la fin de l'animation tandis que la vue en l'état « page 2 » entre en cadre, exactement comme il se comporte avec un animation de transition. Bien sûr, je pourrais toujours jouer avec la duplication de la vue et avoir une vue de frère alors que j'anime le plus en avant et l'enlève de la vue d'ensemble à la fin ... mais il doit y avoir une façon beaucoup plus directe de réaliser cet effet d'animation plutôt simple sans déranger les vues.

probablement quelque chose à dire la couche, mais je ne sais pas quoi, et c'est là où je besoin de votre aide, de gars

de Merci!

Répondre

0

Eh bien, vous pouvez créer un calque, définir le contenu sur une image représentant l'état final de votre vue, que d'appliquer l'animation à cette couche. Lorsque l'animation est terminée, vous pouvez supprimer la couche et changer l'état de la vue.

Je pense que cela fonctionnera mieux que d'instancer une vue entière.

1

J'ai récemment fait une transition de diapositive personnalisée entre les sous-vues dans un contrôleur. Mon approche consistait à saisir une image bitmap de la vue et de la vue, à les ajouter à une vue et à animer cette vue. À la fin, vous pouvez simplement supprimer la vue de transition et afficher la visualisation. Voici un extrait de la méthode de transition:

-(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;} 

Ensuite, dans le sélecteur de swapViewsAtEndOfTransition vous pouvez mettre à jour les vues en conséquence.

0

Les années ont passé, mais je suppose que j'ai trouvé une solution pour vous. Utilisez simplement kCATransitionPush au lieu de kCATransitionReveal. Comme ceci:

- (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; 
}