Tiago Aguiar

5 Passos Para Criar Uma UICollectionView Programaticamente

avatar
Preview Image

Neste artigo quero te mostrar como criar uma UICollectionView programaticamente utilizando a linguagem de programação Swift. E talvez você esteja se perguntando:

Por que fazer desta forma se eu posso utilizar uma interface builder com storyboards ou arquivos xib?

Existe vários motivos e situações onde utilizar uma interface builder pode ser a melhor escolha, porém é fato de que um aplicativo criado programaticamente pode ter muito mais:

  • Flexibilidade
  • Performance
  • Organização
  • Componentização

Além disso, muitas pessoas acabam associando (e até confundindo) uma UICollectionView com a TableView.

Basicamente, a UICollectionView tem os mesmos fundamentos da UITableView. Sua utilização é mais comum em situações mais complexas como na criação de galerias, listagem, carrousel, grids e listas horizontais.

Ou seja, sempre que você tiver dúvidas quando e onde utilizar uma UICollectionView, análise o problema observando se você precisará customizar e ter um maior controle da exibição dos dados.

Particularmente, utilizo a UICollectionView para situações onde preciso ser mais flexível e os dados em questão são dados mais trabalhados, diferente da UITableView onde utilizo para exibir listas mais simples ou até formulários.

Dito isto, vamos aprender como criar uma UICollection View programaticamente passo a passo.

Já leu o artigo passado de como criar um aplicativo iOS do zero? Se ainda não leu, vale a pena conferir ao terminar este artigo.

Antes de prosseguir com esse tutorial, vamos entender os conceitos fundamentais e pré-requisitos para prosseguir.

Pré-requisitos

Este tutorial é para você que já entende fundamentos básicos da:

  • Linguagem de programação Swift
  • E possui o Xcode instalado no Mac OSX

Crie um novo projeto

Agora que você tem tudo pronto para continuar vamos escrever códigos! Aqui está os itens que cobrirei neste artigo:

Abra o Xcode 9. Escolha a opção Create a new Xcode project e escolha a Single View App a aperte Next.

5 Passos Para Criar Uma UICollectionView Programaticamente 01

5 Passos Para Criar Uma UICollectionView Programaticamente 02

Com o Xcode aberto preencha todos os campos obrigatórios para o projeto iOS:

  • Product Name: example – Este é o nome do seu aplicativo.
  • Team: Sua conta Apple (caso já tenha uma)
  • Organization Identifier: co.tiagoaguiar – Este é o nome do seu domínio para identificar o autor do projeto. Caso não tenha, você pode utilizar o meu ou preencher com “com.example”.
  • Organization Name: iOS Developer – Este é o nome da empresa/do autor.
  • Language: Escolha Swift.

Clique em Next para continuar. O Xcode irá te perguntar onde ele deve salvar o projeto “example”.

Escolhar qualquer pasta (ex.: Desktop) para salvar o seu projeto. Tire a seleção de Create Git repository on my Mac para não utilizar o Controle de Versão Git pelo Xcode.

5 Passos Para Criar Uma UICollectionView Programaticamente 03

Quando confirmar o Xcode irá criar o projeto “example” baseado em todas as opções que você forneceu a IDE Xcode.

Tutorial: Como Criar a UICollectionView Programaticamente Em 5 Passos

Primeiro vamos literalmente excluir a Main.storyboard porque não iremos utilizá-la.

Passo 1: Excluindo a Main Storyboard

Clique no projeto e remova a Main.storyboard do Deployment Info -> Main Interface conforme a imagem:

5 Passos Para Criar Uma UICollectionView Programaticamente 04

Desta forma, garantimos 100% que o projeto entenda o nosso objeto de não usar uma interface builder e sim, construí-lo programaticamente com o Xcode.

Passo 2: Dando Vida a ViewController Programaticamente

O próximo passo é abrir o arquivo AppDelegate.swift e adicione o seguinte código no método didFinishLaunchingWithOptions. Este código será necessário para termos uma UIWindow que será nossa View raiz contendo a nossa ViewController principal.

Saiba que o objeto UIWindow é o container raiz onde podemos adicionar ViewControllers à ela através da atribuição rootViewController.

1
2
3
4
5
6
7
8
9
10
11
var window: UIWindow?

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

	window = UIWindow(frame: UIScreen.main.bounds) // 1
	let mainVC = ViewController()
	window?.rootViewController = mainVC // 2
	window?.makeKeyAndVisible() // 3

	return true
}
  1. Nesta linha criamos um objeto do tipo UIWindow que serã o container principal com os tamanhos (frames) iguais do dispositivo atual - seja iPhone ou iPad - desta forma, criamos um container fullscreen com o UIScreen.main.bounds.
  2. Instanciamos uma ViewController e atribuimos a window
  3. Deixa a window visível.

Para garantir que tudo está funcionando como esperado, aconselho a executar pela primeira vez no simulador este aplicativo e adicionar uma cor de fundo a ViewController.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import UIKit

class ViewController: UIViewController {

	override func viewDidLoad() {
		super.viewDidLoad()
		view.backgroundColor = UIColor.green
	}

	override func didReceiveMemoryWarning() {
		super.didReceiveMemoryWarning()
		// Dispose of any resources that can be recreated.
	}

}

Se tudo ocorrer bem durante a criação da UICollectionView programaticamente, você terá uma tela verde FullScreen.

Passo 3: De ViewController Para UICollectionViewController

Em Swift e iOS trabalhamos com a ViewControllers que, em resumo é uma view com uma característica de controller - do padrão MVC.

Logo, toda viewController é uma view!

Abra a classe da UICollectionViewController e você verá que ela tem uma referência a um objeto do tipo UICollectionView. Desta forma, não precisamos necessariamente construir uma UICollectionView porque ela já existe neste tipo de controller.

Eventualmente, se você precisar criar outros elementos na tela como uma TableView ou outro componente, você ficará um pouco limitado já que ela na é uma ViewController genérico e sim uma ViewController onde todo o seu container é uma Coleção.

Continue lendo para ficar mais claro o conceito.

Neste passo vamos trocar a ViewController para a UICollectionViewController.

1
class ViewController: UICollectionViewController {

Depois, vamos adicionar um layout para ela visto que, as UICollections trabalham com tipos de layouts.

O mais comum e simples é o UICollectionViewFlowLayout que é responsável por fazer cada célula da nossa coleção se adaptar de uma forma fluida preenchendo os espaços necessários para ele.

1
2
3
4
5
window = UIWindow(frame: UIScreen.main.bounds)
let layout = UICollectionViewFlowLayout()
let mainVC = ViewController(collectionViewLayout: layout)
window?.rootViewController = mainVC
window?.makeKeyAndVisible()

Passo 4: Adicionando células UICollectionViewCell

Quando trabalhamos com coleções precisamos definir:

  1. tipo da célula: register
  2. número de seções: numberOfSecions
  3. número de linhas (células) da seção: numberOfItems
  4. retorno de uma célula: cellForItemAt
  5. tamanhos das células: sizeForItemAt

Nas próximas linhas, irei explicar passo a passo o que acontece no código da UICollectionViewController.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class ViewController: UICollectionViewController {

	override func viewDidLoad() {
		super.viewDidLoad()
		collectionView?.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "id") // 1
	}

	// 2
	override func numberOfSections(in collectionView: UICollectionView) -> Int {
		return 1
	}

	// 3
	override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
		return 50
	}

	// 4
	override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
		let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "id", for: indexPath)

		cell.backgroundColor = .green

		return cell
	}

}

1. Tipo de Célula

Seguindo a ordem do código-fonte em primeiro lugar temos a declaração: collectionView?.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "id"). Sua função é dizer para a collectionview qual será o tipo de célula (UICollectionViewCell) e seu identificador (id).

Quando criamos células dentro de uma UICollectionView, precisamos sempre definir uma célula do tipo UICollectionViewCell ou qualquer objeto que extenda essa classe. Logo, se quiser criar uma célula customizada para a sua UICollectionView, você terá que criar, obrigatoriamente, uma classe que herda a UICollectionViewCell.

Neste exemplo, como não estamos customizando uma célula com outras Labels e textos por exemplo, deixaremos o padrão. O id, por sua vez, será utlizado pelo método cellForItemAt onde iremos ler o identificador e saber o tipo daquela célula. As vezes é preciso que uma mesma coleção tenha mais de um tipo de célula como: UserCell, LoginCell, etc. Todas elas herdam a UICollectionViewCell.

2. Número de Seções da UICollectionView

O próximo método numberOfSections indica quantas seções a coleção terá. Isso é útil quando você precisa categorizar os seus dados como por exemplo, tipos de filmes (ação, aventura, etc). Ou em um e-commerce onde você categoriza os produtos como eletrônicos e assim por diante.

Veja que neste exemplo, definimos um. Logo, todas as células dessa seção ficaram no mesmo grupo.

3. Número de Linhas da Seção

Neste método definiremos quantas linhas cada seção terá. No nosso exemplo, teremos 50 llinhas em uma única seção. Utilize o método collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int

4. Retornando a Célula Configurada

Este quarto método obrigatório é um pouco mais complexo e por isso, preciso explicá-lo com mais detalhes ainda.

Antes de explicar o método você precisa entender como o iOS constrói as células.

Basicamente, toda vez que o usuário faz uma rolagem em uma lista com 100 linhas por exemplo, as linhas precisam ser construídas. Há 2 maneiras de se fazer isso: a primeira é instanciar uma célula sempre que houver rolagem na tela e a segunda é reutilizar células já construidas e alterar apenas o valor (o dado).

A segunda opção é a melhor e utilizada pelo SDK da Apple.

Dito isto, agora sabemos que o método dequeueReusableCell é responsável por criar as células do tipo UICollectionViewCell e reutilizá-las quando necessário. Essa reutilização é feita através do identificador (id) que registramos no começo do projeto e através do indexPath que é a referência de qual linha e qual seção precisa ser reutilizada.

Execute seu projeto e você verá uma tela parecida com esta:

5 Passos Para Criar Uma UICollectionView Programaticamente

Passo 5: Customizando o Tamanho da UICollection View Cell Programaticamente

Note que cada célula ficou pequena como um quadrado. Isto acontece porque os tamanhos padrões das UICollectionViewCell são de 50 por 50. Logo, para alterar precisaremos de um delegate conhecido como UICollectionViewDelegateFlowLayout.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class ViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout { // 1

	override func viewDidLoad() {
		super.viewDidLoad()
		collectionView?.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "id")
	}

	override func numberOfSections(in collectionView: UICollectionView) -> Int {
		return 1
	}

	override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
		return 50
	}

	override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
		let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "id", for: indexPath)

		cell.backgroundColor = .green

		return cell
	}

	// 2
	func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
		return CGSize(width: collectionView.frame.width, height: 50)
	}

}

1. Protocol UICollectionViewDelegateFlowLayout

Implemente o protocol UICollectionViewDelegateFlowLayout para ter acesso aos métodos referentes ao FlowLayout.


2. Definindo Altura e Largura de Cada Célula

Para definir a largura e a altura de cada UICollectionViewCell programaticamente você precisará sobrescrever o método collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize onde ele pede um retorno do tipo CGSize.

Definimos a largura da própria collection 100% collectionView.frame.width mais 50 de altura.

Execute o seu projeto e você terá uma UICollectionView feita programaticamente do zero.

5 Passos Para Criar Uma UICollectionView Programaticamente

Essa é a dica de hoje espero que coloque em prática e que você realmente aprenda.

  • Compartilhe nas redes sociais com seus amigos
  • Se inscreva no curso completo sobre desenvolvimento iOS aqui.

Maravilha! Em breve você receberá conteúdos exclusivos por e-mail. Continue lendo os artigos para aprender mais sobre programação.