Prática recomendada de animação do iPhone UIView

142

Qual é a melhor prática considerada para animar transições de exibição no iPhone?

Por exemplo, o ViewTransitionsprojeto de amostra da apple usa código como:

CATransition *applicationLoadViewIn = [CATransition animation];
[applicationLoadViewIn setDuration:1];
[applicationLoadViewIn setType:kCATransitionReveal];
[applicationLoadViewIn setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]];
[[myview layer] addAnimation:applicationLoadViewIn forKey:kCATransitionReveal];

mas também existem trechos de código flutuando na rede com a seguinte aparência:

[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.75];
[UIView setAnimationDelegate:self];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:myview cache:YES];
[myview removeFromSuperview];
[UIView commitAnimations];

Qual é a melhor abordagem? Se você também pudesse fornecer um trecho, seria muito apreciado.

NOTA: Não foi possível obter a segunda abordagem para funcionar corretamente.

Keith Fitzgerald
fonte

Respostas:

118

Na seção de referência do UIView sobre o beginAnimations:context:método:

O uso desse método não é recomendado no iPhone OS 4.0 e posterior. Você deve usar os métodos de animação baseados em blocos.

Por exemplo, de animação baseada em bloco com base no comentário de Tom

[UIView transitionWithView:mysuperview 
                  duration:0.75
                   options:UIViewAnimationTransitionFlipFromRight
                animations:^{ 
                    [myview removeFromSuperview]; 
                } 
                completion:nil];
Rafael Vega
fonte
4
Então .. para ser claro, isso significa usar a primeira abordagem (CATransition), não a segunda?
Steve N
2
Sim, é a primeira abordagem (CATransition).
NebulaFox
16
@Steven N, não, significa usar as animações baseadas em blocos UIView. Eles são essencialmente os mesmos que os beginAnimationsamigos, mas usam os recursos de bloqueio / fechamento.
Dan Rosenstark 18/11/2010
36
Sim, Yar está certo. É assim que uma animação de bloco se parece: [UIView transitionWithView:mysuperview duration:0.75 options:UIViewAnimationTransitionFlipFromRight animations:^{ [myview removeFromSuperview]; } completion:nil]Verifique a documentação do UIView para obter detalhes.
Tom van Zummeren
3
Exceto se você deseja suportar os telefones 3.1.3. Então não use blocos.
ZaBlanc 19/03
69

Eu tenho usado o último para muitas animações leves e agradáveis. Você pode usá-lo com duas visões cruzadas, ou esmaecer uma na frente da outra, ou esmaecer. Você pode fotografar uma vista sobre outra como um banner, pode aumentar ou diminuir a visão ... Estou obtendo muita milhagem de beginAnimation/ commitAnimations.

Não pense que tudo o que você pode fazer é:

[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:myview cache:YES];

Aqui está uma amostra:

[UIView beginAnimations:nil context:NULL]; {
    [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
    [UIView setAnimationDuration:1.0];
    [UIView setAnimationDelegate:self];
    if (movingViewIn) {
// after the animation is over, call afterAnimationProceedWithGame
//  to start the game
        [UIView setAnimationDidStopSelector:@selector(afterAnimationProceedWithGame)];

//      [UIView setAnimationRepeatCount:5.0]; // don't forget you can repeat an animation
//      [UIView setAnimationDelay:0.50];
//      [UIView setAnimationRepeatAutoreverses:YES];

        gameView.alpha = 1.0;
        topGameView.alpha = 1.0;
        viewrect1.origin.y = selfrect.size.height - (viewrect1.size.height);
        viewrect2.origin.y = -20;

        topGameView.alpha = 1.0;
    }
    else {
    // call putBackStatusBar after animation to restore the state after this animation
        [UIView setAnimationDidStopSelector:@selector(putBackStatusBar)];
        gameView.alpha = 0.0;
        topGameView.alpha = 0.0;
    }
    [gameView setFrame:viewrect1];
    [topGameView setFrame:viewrect2];

} [UIView commitAnimations];

Como você pode ver, você pode brincar com alfa, quadros e até tamanhos de uma exibição. Brincar. Você pode se surpreender com seus recursos.

mahboudz
fonte
52

A diferença parece ser a quantidade de controle que você precisa sobre a animação.

A CATransitionabordagem oferece mais controle e, portanto, mais coisas para configurar, por exemplo. a função de temporização. Sendo um objeto, você pode armazená-lo para mais tarde, refatorar para apontar todas as suas animações para reduzir o código duplicado etc.

Os UIViewmétodos de classe são convenientes para animações comuns, mas são mais limitados que CATransition. Por exemplo, existem apenas quatro tipos de transição possíveis (virar para a esquerda, virar para a direita, enrolar para cima, enrolar para baixo). Se você quisesse fazer um fade in, teria que cavar para CATransition'sdiminuir a transição ou configurar uma animação explícita do UIViewalfa do seu.

Observe que, CATransitionno Mac OS X, você pode especificar um CoreImagefiltro arbitrário para usar como transição, mas como está agora, não é possível fazer isso no iPhone, o que falta CoreImage.

Ryan McCuaig
fonte
7
Observe que este é um conselho da era do iOS 2.0. Veja a resposta de Rafael Vega sobre métodos baseados em blocos se você estiver no iOS 4.0 ou superior.
Ryan McCuaig
Observe também que o CoreImage agora está disponível a partir do iOS 5, mas apenas alguns de seus recursos. Acredito que você pode usar uma transição CoreImage em uma animação, mas não pode criar filtros CoreImage personalizados no iOS (5).
Aaron Ash
26

Podemos animar imagens no iOS 5 usando esse código simples.

CGRect imageFrame = imageView.frame;
imageFrame.origin.y = self.view.bounds.size.height;

[UIView animateWithDuration:0.5
    delay:1.0
    options: UIViewAnimationCurveEaseOut
    animations:^{
        imageView.frame = imageFrame;
    } 
    completion:^(BOOL finished){
        NSLog(@"Done!");
    }];
Guru
fonte
5
isso também está disponível no iOS 4 e é chamado de animação "baseada em bloco". Não é restrito ao iOS 5 e posterior.
amigos estão dizendo sobre johnbakers
8

Nos UIViewdocumentos, leia sobre esta função para ios4 +

+ (void)transitionFromView:(UIView *)fromView toView:(UIView *)toView duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options completion:(void (^)(BOOL finished))completion
Chris
fonte
6

De qualquer forma, o método "Block" é preferido hoje em dia. Vou explicar o bloco simples abaixo.

Considere o trecho abaixo. bug2 e bug 3 são imageViews. A animação abaixo descreve uma animação com duração de 1 segundo após um atraso de 1 segundo. O bug3 é movido de seu centro para o centro do bug2. Quando a animação estiver concluída, será registrado o "Center Animation Done!".

-(void)centerAnimation:(id)sender
{
NSLog(@"Center animation triggered!");
CGPoint bug2Center = bug2.center;

[UIView animateWithDuration:1
                      delay:1.0
                    options: UIViewAnimationCurveEaseOut
                 animations:^{
                     bug3.center = bug2Center;
                 } 
                 completion:^(BOOL finished){
                     NSLog(@"Center Animation Done!");
                 }];
}

Espero que esteja limpo !!!

Deepukjayan
fonte
2
você atribuiu o bug3.center do CGPoint ao bug3Center e logo depois atribuiu o bug2.center do CGPoint à mesma variável bug3Center? Porque você está fazendo isso ?
Pnizzle
oopss !! isso é um erro de digitação. Atualizado agora.
Deepukjayan
2

Aqui está o código para animação suave, pode ser útil para muitos desenvolvedores.
Encontrei este trecho de código neste tutorial.

CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[animation setAutoreverses:YES];
[animation setFromValue:[NSNumber numberWithFloat:1.3f]];
[animation setToValue:[NSNumber numberWithFloat:1.f]];
[animation setDuration:2.f];
[animation setRemovedOnCompletion:NO];

[animation setFillMode:kCAFillModeForwards];
[[self.myView layer] addAnimation:animation forKey:@"scale"];/// add here any Controller that you want t put Smooth animation.
iPatel
fonte
2

vamos tentar fazer o checkout do Swift 3 ...

UIView.transition(with: mysuperview, duration: 0.75, options:UIViewAnimationOptions.transitionFlipFromRight , animations: {
    myview.removeFromSuperview()
}, completion: nil)
Saurabh Sharma
fonte