Anime elementos nas telas do seu app no SwiftUI
Animações no SwiftUI
Thierri Cegantin
Criado à 4 meses atrás
Animações deixam qualquer aplicativo com um aspecto mais dinâmico e interativo. Algumas vezes elas até instigam os usuários a fuçarem mais no seu app, saindo apertando todos os botões só para descobrir novas animações.
Felizmente, o SwiftUI tem ferramentas que tornam a implementação de animações um processo muito simples e intuitivo. Em linhas gerais, você vai aplicar uma alteração num elemento e indicar para o compilador que aquela alteração de valores deve ser animada.
Vamos conhecer detalhadamente as ferramentas e alguns exemplos de animações para você usar em seus apps.
With Animation: a maneira mais fácil
Antes de aplicar uma animação é preciso codificar a interação que modifica o elemento. Veja esse exemplo bem simples, onde há um quadrado e dois botões na tela. Aumentar e diminuir seu tamanho.
import SwiftUI
struct ContentView: View {
@State var aresta : CGFloat = 50 // Variável interativa
var body: some View {
Rectangle()
.frame(width: aresta, height: aresta) // Uso da variável
HStack{
Text("Diminuir")
.onTapGesture {
// Código para REDUZIR o quadrado
aresta = aresta - CGFloat(50)
}
Text("Aumentar")
.onTapGesture {
// Código para AUMENTAR o quadrado
aresta = aresta + CGFloat(50)
}
}.padding()
}
}
Para deixar o código mais didático foram removidos os Spacer(), responsáveis pelo alinhamento dos elementos.
O resultado obtido é o seguinte:
Note que tudo que foi feito é uma implementação simples que aumenta ou diminui o valor da variável aresta:
aresta = aresta - CGFloat(50)
E isso faz com que o quadrado aumente ou diminua. Porém sem nenhum tipo de animação. Para adicionar uma animação basta encapsular a linha que altera o valor da variável aresta com o método withAnimation:
withAnimation{
aresta = aresta - CGFloat(50)
}
Pronto, agora o compilador já sabe que a alteração da variável aresta deverá ser feita com uma animação. O resultado obtido é será:
Caso você use apenas o withAnimation o compilador aplicará uma animação do tipo “spring” (mola, em português). Cada tipo de animação tem uma velocidade, duração e aceleração especificos. A “spring” padrão faz com que o início da animação tenha uma aceleração maior que o fim, fazendo um repouso suave. O gráfico abaixo demonstra a dinâmica da animação padrão.
Você também pode utilizar o método withAnimation passando os parametros da animação. Por exemplo, para aumentar a elasticidade da mola, basta passar um valor para a propriedade bounce da spring. Utilize valores em 0 e 1, sendo 1 uma super elasticidade.
withAnimation(.spring(bounce: 0.9)){
aresta = aresta - CGFloat(50)
}
Você também pode alterar a propriedade “duration” (duração, em português), para obter animações ainda mais interessantes:
withAnimation(.spring(duration: 0.3, bounce: 0.5)){
aresta = aresta - CGFloat(50)
}
Apesar de alterarmos o tamanho do quadrado qualquer outra propriedade poderia ser animada. Basta que ela esteja dentro da função withAnimation. Por exemplo, a posição do elemento.
import SwiftUI
struct ContentView: View {
@State var offset : CGFloat = 50 // Variável interativa
var body: some View {
Rectangle()
.frame(width: 100, height: 100) // Uso da variável
.offset(y: offset)
HStack{
Text("🔽")
.onTapGesture {
withAnimation(.spring(duration: 0.3, bounce: 0.5)){
offset = offset + CGFloat(50)
}
}
Text("🔼")
.onTapGesture {
withAnimation(.spring(duration: 0.3, bounce: 0.5)){
offset = offset - CGFloat(50)
}
}
}
.padding()
}
}
Use .repeatForever() para uma animação contínua
Caso você queria uma animação contínua é possível utilizar o modificador .repeateForever(). Dessa forma a animação se repetirá numa espécie de “vai e vem”. Veja o exemplo:
withAnimation(.spring(duration: 0.3, bounce: 0.5).repeatForever()){
aresta = aresta - CGFloat(50)
}
Outra forma de animação: Animated Properties
Outra forma de atingir resultados semelhantes aos que conseguimos utilizando o método withAnimation é utilizando o método animation.
A diferença é que esse método deve ser adicionado no objeto cuja propriedade será animada e não método que modifica a propriedade. Por exemplo, a mesma animação que foi feita anteriormente utilizando o método .animation fica da seguinte forma:
import SwiftUI
struct ContentView: View {
@State var offset : CGFloat = 50 // Variável interativa
var body: some View {
Rectangle()
.frame(width: 100, height: 100) // Uso da variável
.offset(y: offset)
.animation(.spring, value: offset)
HStack{
Text("🔽")
.onTapGesture {
offset = offset + CGFloat(50)
}
Text("🔼")
.onTapGesture {
offset = offset - CGFloat(50)
}
}
.padding()
}
}
Note que nos botões que modificam o valor da variável offset não há nenhuma menção a animação. Apenas no retângulo, através da seguinte linha:
.animation(.spring, value: offset)
Todas as modificações que fizemos anteriormente de duração ou elasticidade da mola podem ser feitas no primeiro atributo passado para o método animation. Já o segundo atributo “value” é necessário colocar a variável que deve ser animada.
Dessa forma em qualquer ponto do app que modificarmos a variável offset será sempre feito de maneira animada.
Conclusão
Animações causam um impacto bem interessante no usuário final e felizmente é bem simples de se implementar no SwiftUI. Não deixe de customizar os parâmetros da animação para que ele combine com o contexto do seu aplicativo. Confira também esses outros artigos para enriquecer ainda mais seu conhecimento.
https://developer.apple.com/documentation/swiftui/animations
https://developer.apple.com/videos/play/wwdc2023/10156