Olá! Meu nome é Giovanna Moeller, eu sou instrutora na Alura, e quero te dar boas-vindas ao curso de iOS com SwiftUI voltado para animações!
Giovanna é uma mulher branca de cabelo loiro, liso e comprido, e olhos castanho-escuro. Ela veste uma blusa azul-escuro e está nos estúdios da Alura, sentada em uma cadeira preta em frente a uma parede cinza iluminada em roxo, com uma estante preta com plantas e enfeites à direita.
Nosso projeto será o aplicativo Chef Delivery e vamos implementar a ele novas funcionalidades, como uma tela de boas-vindas focada em animar os componentes, que são:
Além disso, vamos implementar um carrossel na página inicial de forma totalmente automática.
Nesse curso, entenderemos como o SwiftUI consegue tornar determinadas coisas muito mais simples e fáceis para nós, em relação à questão das animações. Uma tela com esse tipo de animação torna a experiência da pessoa usuária muito mais agradável, além de ser mais agradável também visualmente.
Como pré-requisito desse curso, é importante que você já tenha certo conhecimento sobre a construção de layouts simples com Swift UI, e também sobre gerenciamento de estados com Swift UI.
Mas não se preocupe! Temos todos esses conteúdos disponíveis na plataforma, basta acessar a página da nossa escola de Mobile.
Em caso de dúvida, lembre-se de nos chamar no fórum e também no Discord, onde você vai encontrar outras pessoas que estão fazendo esse curso ou já finalizaram!
Espero que você tenha se animado para começar a implementar de fato as animações do projeto e deixar seu aplicativo muito mais bonito.
Te espero para a primeira aula!
Nossa tarefa para esse curso será criar a tela de boas-vindas exibida abaixo, que consiste em bastante animação dos componentes!
Animações são técnicas visuais que adicionam movimento à interface da pessoa usuária. Elas trazem dinamismo e interatividade, então são elementos incríveis para a experiência da pessoa usuária.
Eu, particularmente, acho incríveis os aplicativos que contêm animações, por isso reservamos um curso específico para animações com o SwiftUI.
Retornando ao projeto, nosso primeiro passo será criar a tela de boas-vindas. Para isso, criaremos uma nova pasta dentro de "ChefDelivery", chamada "HomeView".
Dentro dela, vamos criar um novo arquivo do tipo "SwiftUI View" chamado HomeView.swift
.
import SwiftUI
struct HomeView: View {
var body: some View {
Text("Hello, World!")
}
}
struct HomeView_Previews: PreviewProvider {
static var previews: some View {
HomeView()
}
}
Como essa será a primeira tela do nosso aplicativo, precisamos fazer uma modificação no arquivo ChefDeliveryApp.swift
, que por enquanto tem como primeira tela a ContentView()
. Vamos substituí-la por HomeView()
.
import SwiftUI
@main
struct ChefDeliveryApp: App {
var body: some Scene {
WindowGroup {
HomeView()
}
}
}
Feito isso, podemos retornar ao arquivo HomeView.swift
para começar a construir o layout. Primeiramente, vamos remover o elemento Text()
e adicionar uma VStack
.
import SwiftUI
struct HomeView: View {
var body: some View {
VStack {
}
}
}
struct HomeView_Previews: PreviewProvider {
static var previews: some View {
HomeView()
}
}
Entre as chaves dessa VStack
, vamos usar o Text()
para adicionar um texto, que será "Chef Delivery". Em seguida, colocaremos alguns modificadores de propriedade para esse componente.
O primeiro deles será relacionado à fonte (.font()
). Queremos que ela seja bem grande, então vamos usar um tamanho fixo nesse caso. Para isso, passamos .system()
para o modificador e adicionamos a ele a propriedade size
com o valor 40.
Também vamos usar o modificador .fontWeight()
, passando o .heavy
como parâmetro.
Por fim, vamos utilizar um modificador de cor, o .foregroundColor()
. Passaremos para ele a cor "ColorRed", que está dentro de "Assets".
Para finalizar, vamos adicionar o componente Spacer()
, para que seja ocupado todo o espaço disponível e o texto seja posicionado na extremidade superior da tela.
import SwiftUI
struct HomeView: View {
var body: some View {
VStack {
Text("Chef Delivery")
.font(.system(size: 48))
.fontWeight(.heavy)
.foregroundColor(Color("ColorRed"))
Spacer()
}
}
}
struct HomeView_Previews: PreviewProvider {
static var previews: some View {
HomeView()
}
}
Agora nosso objetivo é criar um efeito de opacidade, de modo que, quando a tela aparecer, o texto vá de totalmente transparente até o opaco. Para fazer isso, começamos criando uma propriedade de estado (@State
) logo abaixo da view HomeView
. Ela será do tipo private var
e a chamaremos de isAnimating
.
Essa propriedade de estado será um booleano, ou seja, só possuirá valores de true
(verdadeiro) ou false
(falso). Iremos iniciar como false
, pois o momento em que a tela aparece é quando mudamos para verdadeiro.
import SwiftUI
struct HomeView: View {
@State private var isAnimating = false
var body: some View {
VStack {
Text("Chef Delivery")
.font(.system(size: 48))
.fontWeight(.heavy)
.foregroundColor(Color("ColorRed"))
Spacer()
}
}
}
struct HomeView_Previews: PreviewProvider {
static var previews: some View {
HomeView()
}
}
Como saber quando a tela estiver aparecendo? Para isso, existe um modificador de propriedade chamado .onAppear()
. Vamos aplicá-lo ao VStack
, mas em vez de parênteses após o modificador, abriremos chaves.
Dentro do .onAppear {}
, passaremos que a propriedade isAnimating
é igual a true
.
import SwiftUI
struct HomeView: View {
@State private var isAnimating = false
var body: some View {
VStack {
Text("Chef Delivery")
.font(.system(size: 48))
.fontWeight(.heavy)
.foregroundColor(Color("ColorRed"))
Spacer()
}
.onAppear {
isAnimating = true
}
}
}
struct HomeView_Previews: PreviewProvider {
static var previews: some View {
HomeView()
}
}
Agora podemos adicionar os modificadores de propriedade com base nessa propriedade de estado. Por exemplo: no Text()
, vamos incluir o modificador .opacity()
e, entre parênteses, adicionaremos um operador if
ternário.
Relembrando: o
if
ternário é composto por ponto de interrogação (?
) e dois-pontos (:
).
Entre os parênteses do modificador, vamos digitar isAnimating
seguido de ?
. Com isso, queremos dizer que se isAnimating
for igual a true
, o texto ficará totalmente opaco, então adicionamos o valor 1 após a interrogação. Se a propriedade isAnimating
for igual a false
, ou seja, :
, o valor será 0, sem opacidade.
import SwiftUI
struct HomeView: View {
@State private var isAnimating = false
var body: some View {
VStack {
Text("Chef Delivery")
.font(.system(size: 48))
.fontWeight(.heavy)
.foregroundColor(Color("ColorRed"))
.opacity(isAnimating ? 1 : 0)
Spacer()
}
.onAppear {
isAnimating = true
}
}
}
struct HomeView_Previews: PreviewProvider {
static var previews: some View {
HomeView()
}
}
Ao executar esse código, o resultado no simulador estará igual ao anterior, praticamente sem acontecer nada, pois o texto já vem diretamente opaco. Isso acontece porque não existe nenhuma transição suave entre o estado do isAnimating
.
Ou seja, quando o isAnimating
vai de false
para true
assim que a tela aparece, não existe nenhuma animação suave. Precisamos implementar isso!
withAnimation()
Existe um bloco de código em SwiftUI chamado withAnimation()
, que nos permite adicionar animação às alterações de propriedade. Interessante, não é?
Dentro do modificador .onAppear {}
, vamos começar escrevendo withAnimation()
.
Se digitarmos um ponto (.
) entre os parênteses, serão sugeridas várias opções de animação. A minha animação favorita é a easeInOut()
, pois ela começa devagar, se torna mais rápida, e depois volta a ser devagar.
Vamos selecionar a opção easeInOut(duration:)
, para adicionar também a duração da animação. Por padrão, ela dura 0.25 segundos. Nesse caso, vamos definir a duração como 3 segundos, para visualizar melhor a animação acontecer.
/* Código suprimido */
.onAppear {
withAnimation(.easyInOut(duration: 3))
isAnimating = true
}
/* Código suprimido */
Em seguida, vamos adicionar chaves ao final do withAnimation()
e deslocar a propriedade isAnimating
da linha de código 28 para dentro desse bloco de código.
.onAppear {
withAnimation(.easeInOut(duration: 3)) {
isAnimating = true
}
}
Executando o código com essas modificações, teremos o efeito de opacidade acontecendo com uma animação, que no caso é uma transição suave. Com o bloco de código withAnimation()
, podemos animar as variáveis quando elas mudam de estado.
Vamos adicionar também um modificador de offset (.offset()
). Esse modificador basicamente causa um deslocamento no eixo vertical (y) e no eixo horizontal (x).
Começaremos trabalhando com o eixo vertical, então vamos digitar y
e, após dois-pontos, adicionar a propriedade isAnimating
seguida de uma interrogação.
Queremos dizer que se a propriedade for verdadeira (valor true
), o deslocamento será nulo, então digitamos 0. Se for falsa (valor false
), teremos o deslocamento de -40, para criar um efeito do texto se deslocando de cima para baixo.
.offset(y: isAnimating ? 0 : -40)
Executando o código com essa alteração, teremos o efeito desejado do texto descendo, além da transição suave de 3 segundos, conforme definido anteriormente.
Nesse caso, 3 segundos é um tempo longo, que adicionamos apenas para visualizar a animação acontecer. Podemos alterar para 1.5, um tempo interessante para rodar a animação.
.onAppear { withAnimation(.easeInOut(duration: 1.5)) { isAnimating = true } }
Agora vamos adicionar o subtítulo da tela. Após o componente Text()
referente ao título, colocaremos um novo Text()
, contendo o texto "Peça as suas comidas favoritas no conforto da sua casa".
Incluiremos também alguns modificadores, como:
.font()
: definido como title2
;.padding()
;.multilineTextAlignment()
: definido como .center
para centralizar o texto;.foregroundColor()
: definido como .black
com opacidade (.opacity()
) de 0.7;.opacity()
: definiremos o mesmo que utilizamos para o primeiro Text()
, então isAnimating ? 1 : 0
;.offset()
: também seguiremos o mesmo padrão utilizado para o primeiro Text()
, ou seja, y: isAnimating ? 0 : -40
.É importante mencionar que, às vezes, as animações não funcionam tão bem no simulador, então se acontecer algum bug, não se preocupe, pois o XCode é assim mesmo!
Abaixo, o resultado do código de HomeView.swift
até o momento:
import SwiftUI
struct HomeView: View {
@State private var isAnimating = false
var body: some View {
VStack {
Text("Chef Delivery")
.font(.system(size: 48))
.fontWeight(.heavy)
.foregroundColor(Color("ColorRed"))
.opacity(isAnimating ? 1 : 0)
.offset(y: isAnimating ? 0 : -40)
Text("Peça as suas comidas favoritas no conforto da sua casa.")
.font(.title2)
.padding()
.multilineTextAlignment(.center)
.foregroundColor(.black.opacity(0.7))
.opacity(isAnimating ? 1 : 0)
.offset(y: isAnimating ? 0 : -40)
Spacer()
}
.onAppear {
withAnimation(.easeInOut(duration: 1.5)) {
isAnimating = true
}
}
}
}
struct HomeView_Previews: PreviewProvider {
static var previews: some View {
HomeView()
}
}
Feito isso, teremos dois efeitos de animação aplicados a ambos os textos adicionados: o primeiro de opacidade, e o segundo de offset.
Você já entendeu um pouco mais sobre animações, como podemos utilizar o bloco withAnimation()
para animar quando uma variável tem seu valor alterado, e também como utilizamos o operador ternário para criar modificadores de propriedade com a visualização de animação.
Agora precisamos criar o efeito de desfoque no fundo da tela. Para fazer isso, espero você no próximo vídeo!
Já temos os textos criados na nossa tela. Agora precisamos criar o fundo!
O fundo é composto por dois círculos vermelhos que estão com o efeito de desfoque, nos cantos superior esquerdo e inferior direito da tela. Para criar esse fundo, precisamos aprender sobre um container chamado ZStack
, pois os círculos estão atrás dos textos, da imagem e do botão.
O ZStack
faz referência ao eixo z, que é o eixo de profundidade.
Retornando ao código do arquivo HomeView.swift
, vamos pressionar a tecla "Command" e clicar sobre a view VStack
. Feito isso, selecionaremos a opção "Embed in ZStack".
Teremos o seguinte resultado no código:
import SwiftUI
struct HomeView: View {
@State private var isAnimating = false
var body: some View {
ZStack {
VStack {
Text("Chef Delivery")
.font(.system(size: 48))
.fontWeight(.heavy)
.foregroundColor(Color("ColorRed"))
.opacity(isAnimating ? 1 : 0)
.offset(y: isAnimating ? 0 : -40)
Text("Peça as suas comidas favoritas no conforto da sua casa.")
.font(.title2)
.padding()
.multilineTextAlignment(.center)
.foregroundColor(.black.opacity(0.7))
.opacity(isAnimating ? 1 : 0)
.offset(y: isAnimating ? 0 : -40)
Spacer()
}
}
.onAppear {
withAnimation(.easeInOut(duration: 1.5)) {
isAnimating = true
}
}
}
}
struct HomeView_Previews: PreviewProvider {
static var previews: some View {
HomeView()
}
}
O primeiro componente do ZStack
será um círculo, então vamos escrever Circle()
. Definiremos uma cor de fundo para ele, utilizando o modificador .foregroundColor()
. A cor será "ColorRed", salva em "Assets" e utilizada também no título.
Além desse modificador, vamos utilizar o .frame()
para diminuir o tamanho desse círculo. Para isso, o parâmetro width
será definido como 200.
Agora precisamos adicionar um modificador chamado .position()
. Esse modificador irá definir onde o círculo fica na tela. Para isso, ele recebe dois parâmetros: o x
e o y
, definindo os eixos horizontal e vertical, respectivamente.
Para o x
, vamos passar o valor de 50, para que o círculo fique posicionado um pouco mais à esquerda. Lembrando que os eixos x
e y
iguais a 0, seria correspondente ao canto superior esquerdo da tela. Em seguida, vamos definir o y
com o valor de 100, para movê-lo um pouco para baixo em relação à extremidade do topo.
Para criar o efeito de desfoque, podemos utilizar o modificador .blur()
contendo o parâmetro radius
, que irá receber o valor 60.
Vamos finalizar reduzindo um pouco do vermelho do círculo. Para isso, adicionamos o modificador de propriedade .opacity()
e passaremos o valor 0.5.
import SwiftUI
struct HomeView: View {
@State private var isAnimating = false
var body: some View {
ZStack {
Circle()
.foregroundColor(Color("ColorRed"))
.frame(width: 200)
.position(x: 50, y: 100)
.blur(radius: 60)
.opacity(0.5)
/* Código suprimido */
No momento, temos o seguinte resultado no simulador:
Como o círculo é o primeiro componente do ZStack
, então ele fica atrás dos outros elementos. Caso o VStack
viesse antes do círculo, o VStack
ficaria atrás do círculo, então a ordem no código importa bastante nesse caso.
Vamos copiar o bloco Circle()
que acabamos de criar e colar logo abaixo, pois será adicionado um novo elemento de círculo.
Você deve estar pensando que poderia ser criado um componente para o círculo, já que serão modificadas poucas coisas nesse processo. É verdade, você poderia criar esse componente, mas como não é esse o escopo do nosso curso, vamos manter dessa forma.
Para o segundo círculo, vamos alterar a cor no modificador .foregroundColor
de "ColorRed" para "ColorRedDark", para trazer uma diferença entre os componentes.
Até o momento, temos o seguinte:
import SwiftUI
struct HomeView: View {
@State private var isAnimating = false
var body: some View {
ZStack {
Circle()
.foregroundColor(Color("ColorRed"))
.frame(width: 200)
.position(x: 50, y: 100)
.blur(radius: 60)
.opacity(0.5)
Circle()
.foregroundColor(Color("ColorRedDark"))
.frame(width: 200)
.position(x: 50, y: 100)
.blur(radius: 60)
.opacity(0.5)
/* Código suprimido */
Agora temos um problema: gostaríamos de posicionar o segundo círculo no canto inferior direito da tela. Qual será a .position()
do x
e do y
nesse caso? Será que precisamos testar valores até encontrar o resultado desejado? O que aconteceria se estivéssemos utilizando um iPad, por exemplo, cuja dimensão é bem maior?
Existe uma maneira de saber quais são os valores das extremidades de uma tela. Para fazer isso, podemos utilizar um container oferecido pelo SwiftUI chamado GeometryReader
, que consegue pegar os valores das dimensões do nosso dispositivo.
Vamos pressionar a tecla "Command" e clicar sobre o ZStack
na linha de código 16, para então selecionar a opção "Embed…". Será criado acima do ZStack
um elemento Container {}
, que vamos renomear para GeometryReader
.
Para utilizar o GeometryReader
, precisamos ter acesso a uma variável para dar os valores das dimensões, então logo após a abertura de chaves do GeometryReader
, vamos adicionar geometry in
.
import SwiftUI
struct HomeView: View {
@State private var isAnimating = false
var body: some View {
GeometryReader { geometry in
ZStack {
Circle()
.foregroundColor(Color("ColorRed"))
.frame(width: 200)
.position(x: 50, y: 100)
.blur(radius: 60)
.opacity(0.5)
Circle()
.foregroundColor(Color("ColorRedDark"))
.frame(width: 200)
.position(x: 50, y: 100)
.blur(radius: 60)
.opacity(0.5)
VStack {
Text("Chef Delivery")
.font(.system(size: 48))
.fontWeight(.heavy)
.foregroundColor(Color("ColorRed"))
.opacity(isAnimating ? 1 : 0)
.offset(y: isAnimating ? 0 : -40)
Text("Peça as suas comidas favoritas no conforto da sua casa.")
.font(.title2)
.padding()
.multilineTextAlignment(.center)
.foregroundColor(.black.opacity(0.7))
.opacity(isAnimating ? 1 : 0)
.offset(y: isAnimating ? 0 : -40)
Spacer()
}
}
}
.onAppear {
withAnimation(.easeInOut(duration: 1.5)) {
isAnimating = true
}
}
}
}
struct HomeView_Previews: PreviewProvider {
static var previews: some View {
HomeView()
}
}
Feito isso, a variável geometry
dará todas as informações referentes às extremidades e às posições do nosso dispositivo.
Vamos retornar ao bloco do segundo círculo, e em vez de passar o valor 200 para o parâmetro x
, vamos digitar geometry.size.width
. Dessa forma, será retornada a largura do dispositivo.
Em seguida, faremos uma conta básica de menos 50, adicionando - 50
após o geometry.size.width
, para que o círculo fique posicionado um pouco mais à esquerda na tela.
No caso do y
, vamos digitar geometry.size.height
, correspondente à altura do dispositivo. Da mesma forma, vamos adicionar - 50
para mover o círculo um pouco para cima.
Circle()
.foregroundColor(Color("ColorRedDark"))
.frame(width: 200)
.position(x: geometry.size.width - 50, y: geometry.size.height - 50)
.blur(radius: 60)
.opacity(0.5)
Teremos o seguinte resultado no simulador:
Já temos nosso fundo de desfoque criado, mas ainda precisamos adicionar alguma animação a eles, pois até o momento, quando executamos o código, os textos são animados e os círculos são estáticos.
Vamos trazer um pouco de vida para eles? Te espero para o próximo vídeo!
O curso iOS com SwiftUI: trabalhando com animações e DragGesture possui 74 minutos de vídeos, em um total de 39 atividades. Gostou? Conheça nossos outros cursos de iOS em Mobile, ou leia nossos artigos de Mobile.
Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:
Impulsione a sua carreira com os melhores cursos e faça parte da maior comunidade tech.
1 ano de Alura
Assine o PLUS e garanta:
Formações com mais de 1500 cursos atualizados e novos lançamentos semanais, em Programação, Inteligência Artificial, Front-end, UX & Design, Data Science, Mobile, DevOps e Inovação & Gestão.
A cada curso ou formação concluído, um novo certificado para turbinar seu currículo e LinkedIn.
No Discord, você tem acesso a eventos exclusivos, grupos de estudos e mentorias com especialistas de diferentes áreas.
Faça parte da maior comunidade Dev do país e crie conexões com mais de 120 mil pessoas no Discord.
Acesso ilimitado ao catálogo de Imersões da Alura para praticar conhecimentos em diferentes áreas.
Explore um universo de possibilidades na palma da sua mão. Baixe as aulas para assistir offline, onde e quando quiser.
Acelere o seu aprendizado com a IA da Alura e prepare-se para o mercado internacional.
1 ano de Alura
Todos os benefícios do PLUS e mais vantagens exclusivas:
Luri é nossa inteligência artificial que tira dúvidas, dá exemplos práticos, corrige exercícios e ajuda a mergulhar ainda mais durante as aulas. Você pode conversar com a Luri até 100 mensagens por semana.
Aprenda um novo idioma e expanda seus horizontes profissionais. Cursos de Inglês, Espanhol e Inglês para Devs, 100% focado em tecnologia.
Transforme a sua jornada com benefícios exclusivos e evolua ainda mais na sua carreira.
1 ano de Alura
Todos os benefícios do PRO e mais vantagens exclusivas:
Mensagens ilimitadas para estudar com a Luri, a IA da Alura, disponível 24hs para tirar suas dúvidas, dar exemplos práticos, corrigir exercícios e impulsionar seus estudos.
Envie imagens para a Luri e ela te ajuda a solucionar problemas, identificar erros, esclarecer gráficos, analisar design e muito mais.
Escolha os ebooks da Casa do Código, a editora da Alura, que apoiarão a sua jornada de aprendizado para sempre.