Partilhar via


Animação principal no Xamarin.iOS

Este artigo examina a estrutura Core Animation, mostrando como ela permite animações fluidas e de alto desempenho no UIKit, bem como como usá-la diretamente para controle de animação de nível inferior.

O iOS inclui o Core Animation para fornecer suporte de animação para exibições em seu aplicativo. Todas as animações ultrasuaves no iOS, como rolagem de tabelas e deslizamento entre diferentes modos de exibição, funcionam tão bem quanto eles porque dependem da Core Animation internamente.

As estruturas Core Animation e Core Graphics podem trabalhar juntas para criar belos gráficos 2D animados. Na verdade, o Core Animation pode até transformar gráficos 2D no espaço 3D, criando experiências cinematográficas incríveis. No entanto, para criar gráficos 3D verdadeiros, você precisaria usar algo como OpenGL ES, ou para jogos recorrer a uma API como MonoGame, embora o 3D esteja além do escopo deste artigo.

Animação principal

O iOS usa a estrutura Core Animation para criar efeitos de animação, como transição entre modos de exibição, menus deslizantes e efeitos de rolagem, para citar alguns. Há duas maneiras de trabalhar com animação:

  • Via UIKit, que inclui animações baseadas em visualização, bem como transições animadas entre controladores.
  • Via Core Animation, que cria camadas diretamente, permitindo um controle mais refinado.

Usando a animação UIKit

O UIKit fornece vários recursos que facilitam a adição de animação a um aplicativo. Embora ele use o Core Animation internamente, ele o abstrai para que você trabalhe apenas com exibições e controladores.

Esta seção discute os recursos de animação UIKit, incluindo:

  • Transições entre controladores
  • Transições entre modos de exibição
  • Exibir animação de propriedade

Transições de controlador de exibição

UIViewController fornece suporte interno para a transição entre controladores de exibição por meio do PresentViewController método. Ao usar PresentViewControllero , a transição para o segundo controlador pode opcionalmente ser animada.

Por exemplo, considere um aplicativo com dois controladores, em que tocar em um botão no primeiro controlador chama PresentViewController para exibir um segundo controlador. Para controlar qual animação de transição é usada para mostrar o segundo controlador, basta definir sua ModalTransitionStyle propriedade como mostrado abaixo:

SecondViewController vc2 = new SecondViewController {
  ModalTransitionStyle = UIModalTransitionStyle.PartialCurl
};

Neste caso, uma PartialCurl animação é usada, embora várias outras estejam disponíveis, incluindo:

  • CoverVertical – Desliza para cima a partir da parte inferior da tela
  • CrossDissolve – A visão antiga desaparece e a nova vista desaparece
  • FlipHorizontal - Um flip horizontal da direita para a esquerda. Na demissão, a transição vira da esquerda para a direita.

Para animar a transição, passe true como segundo argumento para PresentViewController:

PresentViewController (vc2, true, null);

A captura de tela a seguir mostra a aparência da transição para o PartialCurl caso:

Esta captura de tela mostra a transição PartialCurl

Exibir transições

Além das transições entre controladores, o UIKit também oferece suporte à animação de transições entre modos de exibição para trocar um modo de exibição por outro.

Por exemplo, digamos que você tinha um controle com UIImageView, onde tocar na imagem deve exibir um segundo UIImageView. Para animar a supervisualização da visualização de imagem para fazer a transição para a segunda visualização de imagem é tão simples quanto chamá-la UIView.Transition, passando-a para o toView e fromView como mostrado abaixo:

UIView.Transition (
  fromView: view1,
  toView: view2,
  duration: 2,
  options: UIViewAnimationOptions.TransitionFlipFromTop |
    UIViewAnimationOptions.CurveEaseInOut,
  completion: () => { Console.WriteLine ("transition complete"); });

UIView.Transition também usa um duration parâmetro que controla por quanto tempo a animação é executada, bem como options para especificar coisas como a animação a ser usada e a função de atenuação. Além disso, você pode especificar um manipulador de conclusão que será chamado quando a animação for concluída.

A captura de tela abaixo mostra a transição animada entre as visualizações de imagem quando TransitionFlipFromTop é usada:

Esta captura de tela mostra a transição animada entre as exibições de imagem quando TransitionFlipFromTop é usado

Exibir animações de propriedade

UIKit suporta a animação de uma variedade de propriedades na UIView classe gratuitamente, incluindo:

  • Frame
  • Limites
  • Center
  • Alfa
  • Transformação
  • Color

Essas animações acontecem implicitamente especificando alterações de propriedade em um NSAction delegado passado para o método estático UIView.Animate . Por exemplo, o código a seguir anima o ponto central de um UIImageView:

pt = imgView.Center;

UIView.Animate (
  duration: 2,
  delay: 0,
  options: UIViewAnimationOptions.CurveEaseInOut |
    UIViewAnimationOptions.Autoreverse,
  animation: () => {
    imgView.Center = new CGPoint (View.Bounds.GetMaxX ()
      - imgView.Frame.Width / 2, pt.Y);},
  completion: () => {
    imgView.Center = pt; }
);

Isso resulta em uma imagem animando para frente e para trás na parte superior da tela, como mostrado abaixo:

Uma imagem animando para frente e para trás na parte superior da tela como a saída

Tal como acontece com o Transition método, Animate permite que a duração seja definida, juntamente com a função de atenuação. Este exemplo também usou a UIViewAnimationOptions.Autoreverse opção, que faz com que a animação seja animada do valor de volta para o inicial. No entanto, o código também define o Center retorno ao seu valor inicial em um manipulador de conclusão. Enquanto uma animação está interpolando valores de propriedade ao longo do tempo, o valor de modelo real da propriedade é sempre o valor final que foi definido. Neste exemplo, o valor é um ponto próximo ao lado direito da superexibição. Sem definir o Center para o ponto inicial, que é onde a animação é concluída devido ao Autoreverse ser definido, a imagem voltaria para o lado direito após a conclusão da animação, como mostrado abaixo:

Sem definir o Centro para o ponto inicial, a imagem voltaria para o lado direito após a conclusão da animação

Usando a animação principal

UIView As animações permitem muita capacidade e devem ser usadas se possível devido à facilidade de implementação. Como mencionado anteriormente, as animações UIView usam a estrutura Core Animation. No entanto, algumas coisas não podem ser feitas com UIView animações, como animar propriedades adicionais que não podem ser animadas com uma exibição ou interpolar ao longo de um caminho não linear. Nesses casos em que você precisa de um controle mais fino, a Core Animation também pode ser usada diretamente.

Camadas

Ao trabalhar com o Core Animation, a animação acontece por meio de camadas, que são do tipo CALayer. Uma camada é conceitualmente semelhante a uma exibição na medida em que há uma hierarquia de camadas, assim como há uma hierarquia de exibição. Na verdade, camadas de modos de exibição posteriores, com o modo de exibição adicionando suporte para interação do usuário. Você pode acessar a camada de qualquer modo de exibição através da propriedade do modo de Layer exibição. Na verdade, o contexto usado no Draw método de UIView é realmente criado a partir da camada. Internamente, a camada que suporta a UIView tem seu delegado definido para a própria exibição, que é o que chama Draw. Então, ao desenhar para um UIView, você está realmente desenhando para sua camada.

As animações de camada podem ser implícitas ou explícitas. As animações implícitas são declarativas. Você simplesmente declara quais propriedades de camada devem ser alteradas e a animação simplesmente funciona. As animações explícitas, por outro lado, são criadas por meio de uma classe de animação que é adicionada a uma camada. As animações explícitas permitem o controle de adição sobre como uma animação é criada. As seções a seguir se aprofundam em animações implícitas e explícitas.

Animações implícitas

Uma maneira de animar as propriedades de uma camada é por meio de uma animação implícita. UIView As animações criam animações implícitas. No entanto, você também pode criar animações implícitas diretamente em uma camada.

Por exemplo, o código a seguir define uma camada de Contents uma imagem, define uma largura e cor de borda e adiciona a camada como uma subcamada da camada da exibição:

public override void ViewDidLoad ()
{
  base.ViewDidLoad ();

  layer = new CALayer ();
  layer.Bounds = new CGRect (0, 0, 50, 50);
  layer.Position = new CGPoint (50, 50);
  layer.Contents = UIImage.FromFile ("monkey2.png").CGImage;
  layer.ContentsGravity = CALayer.GravityResize;
  layer.BorderWidth = 1.5f;
  layer.BorderColor = UIColor.Green.CGColor;

  View.Layer.AddSublayer (layer);
}

Para adicionar uma animação implícita para a camada, basta encapsular as alterações de propriedade em um CATransactionarquivo . Isso permite animar propriedades que não seriam animáveis com uma animação de exibição, como o BorderWidth e BorderColor como mostrado abaixo:

public override void ViewDidAppear (bool animated)
{
  base.ViewDidAppear (animated);

  CATransaction.Begin ();
  CATransaction.AnimationDuration = 10;
  layer.Position = new CGPoint (50, 400);
  layer.BorderWidth = 5.0f;
  layer.BorderColor = UIColor.Red.CGColor;
  CATransaction.Commit ();
}

Esse código também anima o Position, que é a localização do ponto de ancoragem da camada medido a partir do canto superior esquerdo das coordenadas da supercamada. O ponto de ancoragem de uma camada é um ponto normalizado dentro do sistema de coordenadas da camada.

A figura a seguir mostra a posição e o ponto de ancoragem:

Esta figura mostra a posição e o ponto de ancoragem

Quando o exemplo é executado, o Position, BorderWidth e BorderColor animar conforme mostrado nas seguintes capturas de tela:

Quando o exemplo é executado, Position, BorderWidth e BorderColor são animados conforme mostrado

Animações explícitas

Além das animações implícitas, a Animação Principal inclui uma variedade de classes que herdam a partir daí CAAnimation , permitindo encapsular animações que são adicionadas explicitamente a uma camada. Eles permitem um controle mais refinado sobre animações, como modificar o valor inicial de uma animação, agrupar animações e especificar quadros-chave para permitir caminhos não lineares.

O código a seguir mostra um exemplo de uma animação explícita usando um CAKeyframeAnimation para a camada mostrada anteriormente (na seção Animação Implícita):

public override void ViewDidAppear (bool animated)
{
  base.ViewDidAppear (animated);

  // get the initial value to start the animation from
  CGPoint fromPt = layer.Position;

  /* set the position to coincide with the final animation value
  to prevent it from snapping back to the starting position
  after the animation completes*/
  layer.Position = new CGPoint (200, 300);

  // create a path for the animation to follow
  CGPath path = new CGPath ();
  path.AddLines (new CGPoint[] { fromPt, new CGPoint (50, 300), new CGPoint (200, 50), new CGPoint (200, 300) });

  // create a keyframe animation for the position using the path
  CAKeyFrameAnimation animPosition = (CAKeyFrameAnimation)CAKeyFrameAnimation.FromKeyPath ("position");
  animPosition.Path = path;
  animPosition.Duration = 2;

  // add the animation to the layer.
  /* the "position" key is used to overwrite the implicit animation created
  when the layer positino is set above*/
  layer.AddAnimation (animPosition, "position");
}

Esse código altera o Position da camada criando um caminho que é usado para definir uma animação de quadro-chave. Observe que a camada é Position definida como o valor final do Position da animação. Sem isso, a camada retornaria abruptamente à sua Position anterior à animação, pois a animação altera apenas o valor da apresentação e não o valor real do modelo. Ao definir o valor do modelo para o valor final da animação, a camada permanece no lugar no final da animação.

As capturas de tela a seguir mostram a camada que contém a imagem animada pelo caminho especificado:

Esta captura de tela mostra a camada que contém a imagem animando através do caminho especificado

Resumo

Neste artigo, analisamos os recursos de animação fornecidos por meio das estruturas de animação principal. Examinamos a Animação Principal, mostrando como ela alimenta as animações no UIKit e como ela pode ser usada diretamente para o controle de animação de nível inferior.