Olá, sou Ândriu!
Audiodescrição: Ândriu é uma pessoa de pele clara, de cabelo castanho escuro. Veste uma camiseta azul escuro com o logo da Alura.
Boas-vindas a mais um curso de iOS nesta formação de ViewCode. A ideia é avançarmos nossos conhecimentos com ViewCode, aprendendo a trabalhar principalmente com o CollectionView (coleções de Views).
O objetivo do curso é adicionar uma funcionalidade a mais no nosso aplicativo Cinetopia. Por exemplo, a pessoa usuária pode favoritar alguns filmes que deseja assistir mais tarde. Podemos apresentar isso através de uma coleção de filmes, que em UIKit
chamamos de UICollectionView
. Vamos aprender como configurar uma CollectionView
. Há várias etapas para que isso funcione.
Aprenderemos a trabalhar com o cabeçalho (header) da CollectionView
. Criaremos células personalizadas e também veremos como tratar eventos da pessoa usuária, como a nossa Collection
, como, por exemplo, a ação de desfavoritar os filmes. Além disso, aprenderemos a trabalhar com a troca de telas, utilizando a TabBar
, que é o menu de navegação inferior.
Como pré-requisito, seria interessante você ter concluído os cursos anteriores desta formação de ViewCode ou possuir conhecimentos equivalentes. Dessa maneira, você conseguirá acompanhar conosco sem nenhum problema.
Esse é o conteúdo que vamos explorar durante este curso e aguardamos você na primeira aula!
Para iniciar o curso, entenderemos a demanda com a qual trabalharemos daqui em diante.
A proposta consiste em dar continuidade ao desenvolvimento do projeto Cinetopia, um aplicativo que lista os filmes mais populares atualmente.
Já possuímos algumas alterações que abordaremos ao longo deste curso, especialmente em relação à funcionalidade de favoritar. A intenção é criar uma opção que permita às pessoas usuárias salvar os filmes de seu interesse para visualização posterior. Essa implementação será realizada por meio do desenvolvimento de um botão de favoritos.
A dinâmica do projeto é a seguinte: já temos esta tela onde lista os filmes, mas ainda não temos o botão favoritar. Então, a pessoa usuária vai poder escolher quais filmes deseja favoritar, e vamos mostrar isso em uma tela de filmes favoritos. Esta tela está no ícone de coração do lado inferior direito do aplicativo.
A ideia é construir uma coleção de filmes, utilizaremos a CollectionView
para representar esses filmes favoritados. A pessoa usuária também pode desfavoritar o filme. Quando voltamos à tela inicial, os filmes que foram favoritados já não estão mais favoritados.
Vamos explorar um pouco sobre a navegação utilizando a TabBar
(menu inferior). A ideia é criarmos uma TabBar
, que é esse menu inferior que temos no aplicativo, onde conseguimos alterar a tela de acordo com o item da TabBar
que clicamos. Isso ajuda a conseguir colocar mais funcionalidades no aplicativo. Muitos aplicativos hoje utilizam esse recurso da TabBar
.
Essa é a principal demanda que temos daqui para frente, trabalhar com ViewCode
, utilizar a CollectionView
e também criar a TabBar
.
Relembrando a estrutura do nosso projeto, no lado esquerdo superior, encontramos a hierarquia de pastas do projeto Cinetopia
. Uma pasta contém as classes de serviço (Services
), outra abriga a célula (Cells
), a pasta Models
apresenta a struct
de filme, e há também a pasta ViewControllers
.
A proposta é criar um novo ViewController
para representar a tela de favoritos e iniciar gradualmente a implementação da CollectionView, o componente principal que abordaremos no início do curso.
Vamos lá.
Com o mouse sobre a pasta ViewControllers
, clicamos com o botão direito, selecionando "novo arquivo" ("New file"), o que abre uma tela onde escolhemos um template de arquivo. Optamos pela categoria "Cocoa Touch Class" e clicamos em "Next", que oferece diversos templates. Já temos o template do ViewController
selecionado. Mantendo esse template e nomeando o arquivo como FavoriteMoviesViewController
. Após escolhermos o nome, clicamos em "Next" e em "Create".
import UIKit
class FavoriteMoviesViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
// comentários omitidos
O arquivo já traz o template de um ViewController
com os métodos de ciclo de vida da View, incluindo o ViewDidLoad. Não utilizaremos isso que veio comentado, então apagamos. Nossa intenção é iniciar a configuração da tela.
Manteremos a mesma cor de fundo das outras telas que já foram desenvolvidas. Para alterar a cor, na linha 15, pegamos a referência da view.backgroundColor
e colocamos a cor desejada, que será .backgroundColor
, definida nos cursos anteriores.
Se quiser conhecer o valor dessa cor, que é uma cor customizada e não nativa, seguramos a tecla "Command" do teclado, clicamos nela, e abre-se a pasta Assets
, onde já temos as cores do Design System do nosso app.
import UIKit
class FavoriteMoviesViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .background
}
}
A cor de fundo será aquela que especificamos no nosso código. Retorno ao arquivo FavoriteMovies
, e uma das maiores dificuldades enfrentadas ao trabalhar com ViewCode, em comparação com o Storyboard, é que não é possível visualizar as alterações à medida que o código é escrito e a View é construída.
Com o recurso introduzido pelo SwiftUI de pré-visualização, nas versões anteriores do iOS, já conseguíamos usar um protocolo chamado UIViewRepresentable
para aproveitar a pré-visualização do SwiftUI.
Nas versões mais recentes do iOS, por exemplo, utilizamos o iPhone 15 com o iOS 17, apresentando uma configuração um pouco mais simples. Após fecharmos o nosso ViewController
na linha 17, é possível pressionar "Enter" duas vezes. Podemos empregar a hashtag Preview
e indicar o ViewController
desejado para a pré-visualização, neste caso, o recém-criado FavoriteMoviesViewController()
.
import UIKit
class FavoriteMoviesViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .background
}
}
#Preview {
FavoriteMoviesViewController()
}
Note que à direita, a tela de pré-visualização é aberta automaticamente. Às vezes, é necessário clicar no botão "Atualizar" do lado direito de "Preview paused" para carregá-la. Esse recurso é especialmente útil para quem está começando a aprender a trabalhar com ViewCode, pois permite digitar o código e testar simultaneamente por meio da pré-visualização.
Se desejarmos experimentar um fundo diferente, podemos definir .yellow
, e a alteração é refletida em tempo real. Assim, conseguimos visualizar as mudanças instantaneamente. Retornamos à cor anterior.
Essa é a configuração inicial da tela de filmes favoritos que vamos criar, e a partir do próximo vídeo começaremos a aprender como é que trabalhamos com a CollectionView
.
Continuando, a proposta consiste em construir uma grade que representa cada filme favorito.
import UIKit
class FavoriteMoviesViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .background
}
}
#Preview {
FavoriteMoviesViewController()
}
Recapitulando, buscamos criar uma tela semelhante àquela que exibe os filmes marcados como favoritos pela pessoa usuária, em "Meus filmes favritos", onde há os filmes marcados como favoritos em formato de grade com duas colunas em rolagem vertical. Observamos que há uma coleção de filmes, e a CollectionView
tem a capacidade de organizar essas coleções.
Essas coleções podem se dispor tanto na horizontal quanto na vertical. Em outras palavras, é possível ter uma coleção de filmes com múltiplos itens, permitindo a rolagem horizontal. No entanto, nosso foco, neste caso, é implementar a rolagem vertical, apresentando uma lista de filmes na qual podemos realizar a navegação vertical.
UICollectionView
Para começar, vamos retornar ao arquivo que criamos anteriormente, que é o FavoriteMoviesViewController
e na linha 10, onde declaramos o nome da classe, vamos teclar um "Enter", colocar um marcador, para ajudar a organizar o nosso código. Digitamos mark, dois pontos e UI Components
e declaramos todos os componentes visuais que criamos nesse arquivo.
Incluiremos outra marcação, denominada View Life Cycle
, para atender a este método abaixo, que descreve o ciclo de vida da View. Na linha 22, criaremos mais um marcador, chamado ClassMethod
, para agrupar todos os métodos da classe.
import UIKit
class FavoriteMoviesViewController: UIViewController {
// MARK: - UI Components
// MARK: - View life cycle
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .background
}
// MARK: - Class methods
}
#Preview {
FavoriteMoviesViewController()
}
Assim, organizamos nossos códigos de maneira mais eficiente.
Na linha 12, onde criamos o marcador de UI Components
, ou seja, todos os componentes de UI, inseriremos nesta parte. Na linha 14, declaramos a collectionView
. Criamos uma CollectionView
usando o ViewCode, private lazy var
, chamamos de CollectionView
, e ela vai ser do tipo UICollectionView
. Colocamos um sinal de igual, abrimos e fechamos chaves, e ao final da linha 16 (fechamento das chaves), precisamos instanciar, então abrimos e fechamos parêntese para instanciar a CollectionView
.
import UIKit
class FavoriteMoviesViewController: UIViewController {
// MARK: - UI Components
private lazy var collectionView: UICollectionView = {
}()
// MARK: - View life cycle
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .background
}
// MARK: - Class methods
}
#Preview {
FavoriteMoviesViewController()
}
Chamamos isso de variável computada, conseguimos fazer isso com vários tipos, não só de componentes de interface do usuário, como por exemplo, com String, com Array, qualquer tipo de variável conseguimos declarar ela desse jeito.
Variável computada é quando configuramos essa variável para fazer algum processamento antes de utilizá-la, que é o que vamos fazer neste caso, então a CollectionView
precisa de algumas características, que vamos ver agora, para que ela funcione, então já vamos deixá-la configurada nessa variável computada.
Criamos uma collectionView
, ela é igual a UICollectionView
, quando instanciamos a collectionView
, ela tem um método construtor, que é esse onde passamos o frame, e passamos um CollectionViewLayout
. Escolhemos esta opção.
O frame podemos passar como 0
, não tem problema, e o CollectionViewLayout
, que precisamos passar por parâmetro, vamos descobrir isso juntos.
Antes da declaração da collectionView
, na linha 15, criaremos um UICollectionViewLayout()
. Para ser passado como parâmetro, o chamaremos de layout, que será equivalente a um UICollectionViewFlowLayout()
, e o inicializaremos sem configurações específicas.
import UIKit
class FavoriteMoviesViewController: UIViewController {
// MARK: - UI Components
private lazy var collectionView: UICollectionView = {
let layout = UICollectionViewFlowLayout()
let collectionView = UICollectionView(frame: .zero,
collectionViewLayout: UICollectionViewLayout)
}()
// MARK: - View life cycle
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .background
}
// MARK: - Class methods
}
#Preview {
FavoriteMoviesViewController()
}
O UICollectionViewFlowLayout
auxilia na configuração de aspectos como o tamanho de cada item da CollectionView
e a direção da rolagem. Dispõe de várias opções de configuração no CollectionViewFlowLayout
que exploraremos mais adiante no curso; portanto, neste momento, evitaremos uma análise detalhada, pois haverá uma aula específica para ajustar os itens da collectionView
.
Neste ponto, apenas necessitamos passá-lo como parâmetro na collectionView
:
import UIKit
class FavoriteMoviesViewController: UIViewController {
// MARK: - UI Components
private lazy var collectionView: UICollectionView = {
let layout = UICollectionViewFlowLayout()
let collectionView = UICollectionView(frame: .zero,
collectionViewLayout: layout)
}()
// MARK: - View life cycle
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .background
}
// MARK: - Class methods
}
#Preview {
FavoriteMoviesViewController()
}
Concluído esse passo, começamos a configurar algumas características. Por exemplo, alteraremos o fundo para amarelo. Poderia ser qualquer cor, mas escolhemos uma cor útil para visualizar a CollectionView
na tela. Posteriormente, removeremos o fundo dela. Atualmente, estamos aplicando a cor amarela apenas para facilitar a visualização na tela.
E a última configuração, como vamos utilizar Constraints para adicionar a CollectionView
na tela, desativamos uma configuração que se chama TranslateAutoResizeMaxIntoConstraints
, então quando usamos Constraints temos que desativar essa configuração. Então por isso estamos passando como falso.
Feito isso já temos tudo que uma CollectionView
minimamente precisa para mostrar na tela, nesse momento não vamos configurar os métodos de DataSource, iremos apenas adicioná-la na tela. Digitamos return, return da CollectionView
que criamos.
import UIKit
class FavoriteMoviesViewController: UIViewController {
// MARK: - UI Components
private lazy var collectionView: UICollectionView = {
let layout = UICollectionViewFlowLayout()
let collectionView = UICollectionView(frame: .zero,
collectionViewLayout: layout)
collectionView.backgroundColor = .yellow
collectionView.translatesAutoresizingMaskIntoConstraints = false
return collectionView
}()
// MARK: - View life cycle
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .background
}
// MARK: - Class methods
}
#Preview {
FavoriteMoviesViewController()
}
Após isso já podemos adicionar a CollectionView
na tela, então vamos começar aqui criando um método para adicionar essas Constraints. Na linha 32 teclamos "Enter" e criamos um método, então private func setupConstraints()
.
Relembrando, Constraints são as configurações que adicionamos nos elementos visuais para que eles apareçam na tela, então se desejamos adicionar um elemento acima temos que adicionar Constraints no topo, podemos colocar uma altura, podemos prender a esquerda e a direita, então tem várias formas de se trabalhar com Constraints.
Criamos o método na linha 33 SetupConstraints()
, precisamos chamar esse método de algum lugar para tudo o que programamos dentro ser executado e vamos chamar ele dentro do método ViewDidLoad()
. Então logo após a linha 27 onde setamos a cor de fundo vamos chamar esse método SetupConstraints
.
import UIKit
class FavoriteMoviesViewController: UIViewController {
// MARK: - UI Components
private lazy var collectionView: UICollectionView = {
let layout = UICollectionViewFlowLayout()
let collectionView = UICollectionView(frame: .zero,
collectionViewLayout: layout)
collectionView.backgroundColor = .yellow
collectionView.translatesAutoresizingMaskIntoConstraints = false
return collectionView
}()
// MARK: - View life cycle
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .background
setupConstraints()
}
// MARK: - Class methods
private func setupConstraints() {
}
}
#Preview {
FavoriteMoviesViewController()
}
Na sequência, continuaremos com as configurações das Constraints para que a CollectionView
apareça na tela.
O curso iOS com ViewCode: construa layouts e menu inferior com UICollectionView e TabBar possui 216 minutos de vídeos, em um total de 64 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.