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 PresentViewController
o , 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 telaCrossDissolve
– A visão antiga desaparece e a nova vista desapareceFlipHorizontal
- 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:
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:
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:
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:
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 CATransaction
arquivo . 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:
Quando o exemplo é executado, o Position
, BorderWidth
e BorderColor
animar conforme mostrado nas seguintes capturas de tela:
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:
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.