2010-07-01 21 views
6

Bir görünümün iki durumu arasında animasyon uygulamak istiyorum. Örneğin, bir etiketle bir görüşüme sahip olduğumu ve etiketin metnini değiştirdiğimde bir animasyonun sayfa çevirme olarak değiştiğini söyleyin.Özel bir görüntüyü kullanarak bir görünümün iki durumu arasında animasyon gerçekleştirin

Şimdi tabii bir [UIView setAnimationTransition:forView:cache:] ile yapabilirsiniz:

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

... ama sonra kendi özel animasyon kullanamaz, sen hoşlar (yerleşik animasyonlara sıkışmış ancak ihtiyaçlarım için uygun değiller.

Yani diğer bir seçenek görünümün katmana bir CAAnimation eklemektir:

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

Sonra Çekirdek Animasyon yapmanız sağlayan her türlü animasyon belirlemekte serbesttir. CATransition animasyonunu, örneğin kCATransitionReveal tanımladığımda bu iyi çalışır: "sayfa 2" durumundaki bir görünüm, "sayfa 1" durumunda göründüğünün altında görünür. Ben, örneğin bir CABasicAnimation için için animasyon tanımlarken

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

Ancak, bakış tek tek devlet görülebilir.

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

Bunun yerine, bir davranan tam olarak, "sayfa 2" halde görünüşüdür çerçeve içine gelir ise animasyonun sonuna kadar görünür kalması "sayfa 1" durumuna görünümü istiyoruz geçiş animasyonu.

Tabii ki, her zaman en yakın olanı canlandırıp tamamlandıktan sonra görüntüyü kaldırırken, görüntüyü çoğaltmak ve bir kardeşi olarak görünmekle uğraşabilirim ... ama elde etmek için çok daha düz bir yol olmalı. Bu oldukça basit animasyon etkisi ile görüşlerini karıştırmadan. , Erkek erkeğe :)

Teşekkür

Muhtemelen bir şey tabakasını anlatmak, ama sonra ne olduğunu bilmiyorum, ve yardımına ihtiyacım orası!

cevap

0

Peki, bir katman oluşturabilir, görüntüyü son halinizi temsil eden bir görüntüye ayarlarsanız, animasyonu bu katmana uygulayabilirsiniz. Animasyon tamamlandığında, katmanı kaldırabilir ve görünüm durumunu değiştirebilirsiniz.

Bence bu, tüm manzarayı anlatandan daha iyi çalışacaktır.

1

Yakın zamanda denetleyicideki alt görünümler arasında özel bir geçiş geçişi yaptım. Benim yaklaşımım, görüntülemenin ve görünümün bir bitmapini almak, onları bir görünüme eklemek ve bu görünümü canlandırmaktı. Sonunda geçiş görünümünü kaldırabilir ve görüntüleyebilirsiniz.

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

Sonra swapViewsAtEndOfTransition seçicisi içinde buna göre görünümleri güncelleyebilirsiniz: İşte pasajı geçiş yöntemidir.

0

Yıllar geçti ama sanırım sizin için bir çözüm buldum. Sadece kCATransitionReveal yerine kCATransitionPush kullanın. Bunun gibi:

- (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; 
} 
İlgili konular