Académique Documents
Professionnel Documents
Culture Documents
Seja você iniciante ou Expert, dominar esse componente irá te ajudar a criar aplicativos de
mercado além de aumentar a sua capacidade de criação de novos projetos. Isso porque a
UITableView está presente em mais de 80% dos aplicativos já criados.
A UITableView permite que o usuário final do aplicativo faça duas coisas que são, na minha
opinião, essenciais na era da informação:
1. Listar dados (de uma forma elegante, customizada e eficiente)
2. Permitir a interação dos dados com outras Views (ver detalhes, reordenar, excluir, etc)
Ao final desse eBook você já estará dominando esse componente e estará na frente de muitas
pessoas. Acredito que esse componente é apenas 20% de todos os componentes fornecidos
pela Apple, mas é capaz de estar presente em 80% do seu projeto.
COMO CRIEI UM APLICATIVO PROFISSIONAL DO ZERO
EM 88 DIAS SEM NUNCA TER ESCRITO UMA LINHA DE
CÓDIGO SWIFT OU USADO O XCODE!
Meu nome é Tiago Aguiar, sou Desenvolvedor de Software Sênior (tanto
Web quanto Mobile) e uso meu tempo para compartilhar experiências que
transformam "pessoas comuns" em Desenvolvedores & Designers
Extraordinários. Tudo através de videos, insights, artigos e produtos na web.
Desde 2012, onde comecei minha jornada mobile, crio aplicativos Android pessoais e para
empresas. Porém, eu queria sair da minha zona de conforto, queria me aventurar no mundo
Apple por sempre admirar os produtos extraordinários criado pela empresa. De fato, eles são
referências em tudo que faço. Inclusive esta fonte de texto que você está lendo agora foi
pensado com calma em busca da fonte perfeita para a sua leitura ;-)
Como falei, eu queria sair da minha zona de conforto e criei a oportunidade (um dia eu te conto
como você cria oportunidades) para desenvolver aplicativos iOS dentro da startup que estou
onde comecei a coordenar um time de desenvolvedores.
Em Janeiro de 2016 eu decidi fazer isso do absoluto ZERO, sem mesmo nunca ter encostado
em um Mac, literalmente. Não conhecia Xcode, nem Swift, nem Objective-C. Nada!
Eu acreditava ser simples, mas nunca fácil. Logo, eu consumi todo o tipo de material que você
possa imaginar, isso porque eu tinha dois obstáculos nada pequenos...
… meu tempo era limitado porque eu não tinha um Mac e tinha que ser
feito no trabalho, dentro de 8h (isso contando que eu não ficava 8h
nisso). E também tinha que ser perfeito porque era um aplicativo
profissional. Usado por mais de 50.000 pessoas.
Pra você entender melhor, minha missão era reescrever do absoluto
zero um aplicativo iOS escrito em Objective-C para a nova linguagem
Swift (na época). Detalhe: não sabia Objective-C e nem mesmo Swift.
No fim da história eu consegui fazer isso em 88 dias. O aplicativo estava
pronto totalmente em Swift (em um outro momento conto com mais detalhes)!
O que eu quero mostrar aqui com a minha história é que desenvolver qualquer aplicativo ou
mudar de linguagem de programação é uma tarefa ardua porém simples e que todos podemos
fazer. Você só precisa de 2 coisas:
1. O desejo irrazoável pra fazer seu projeto acontecer!
2. O método certo. Conhecer os atalhos que te colocam um passo a frente cada dia.
Simples assim!
E você já tem o atalho principal em suas mãos agora. Dominar a UITableView. Agora
você precisa pegar esse atalho e colocar um desejo irrazoável pra fazer seu projeto acontecer
Agora que você já sabe que o seu primeiro passo é dominar a UITableView, vamos
começar!
PASSO #0: DEFINIR A IDEIA
Além de compartilhar com você meu conhecimento sobre UITableView mostrando
exemplos práticos do básico à maestria, quero mostrar com ideias de projetos que são de fato,
aplicadas no "campo de batalha". Isto é, ideias de projetos reais que você pode aplicar em
qualquer lugar, seja no seu trabalho ou projeto pessoal.
Logo, o primeiro passo antes de escrever uma linha sequer de código é definir o que vamos
criar.
Criaremos um aplicativo que listará os produtos de uma loja virtual de jogos digitais.
Nosso aplicativo passará por vários estágios. Desde uma listagem básica até a arte final. Isso
porque quero te ensinar os princípios por traz de uma UITableView e como você pode ir
"lapidando" o seu projeto tornando-o cada vez melhor.
PASSO #1: CRIANDO O PROJETO
Abra seu Xcode [ cmd + space ] e clique em criar novo projeto [ Create a new Xcode project
].
Selecione a opção [ Single View Application ] para criar um aplicativo comum do início.
Adicione as seguintes informações para construir o aplicativo:
● Product Name: <Nome do Seu Aplicativo>
● Organization Name: <Nome da Organização>
● Team: <Sua Equipe> (Você pode criar com seu Apple ID)
● Organization Identifier: <usado como um identificador único do seu aplicativo>
● Language: Swift
● Devices: Universal
Escolha seu [ workspace ] para salvar o projeto. Use Core, Data Unit Tests,
Include UI Tests, não serão necessários.
Caso tenha problemas com o parâmetro [ team ], selecione [ Add an Account… ] e crie uma
identifação com seu Apple ID.
Pronto! Agora você já tem um projeto iOS inicial para começar a brincar.
PASSO #2: CRIANDO A View UITableView
A primeira dica aqui é começar a modelar a camada de view do seu aplicativo. Logo, vamos
selecionar o arquivo main.storyboard e começar a construir nossa UITableView
(bem simples para começar).
A esquerda da tela é possível selecionar a View Controller no qual você está
trabalhando…
… e logo abaixo, o tamanho do dispositivo para visualizar como está ficando a View …
Como boas práticas, vamos incorporar nossa View Controller padrão à uma
Navigation View Controller que será responsável pela navegação superior, bem
como título da nossa view.
É bem simples! Basta selecionar a View Controller, clicar em Editor > EmbedIn >
Navigation Controller.
Agora a sua View Controller possui uma Navigation Controller que poderá
abrir menus, ir e vir de views futuramente.
Adicione um título ao seu aplicativo clicando Navigation Item que apareceu no menu da
storyboard.
No menu inferior a direita você encontra uma variedade rica de componentes nativos que o
`SDK` do iOS (kit de desenvolvimento de software) fornece. Hoje vamos usar a
UITableView.
Selecione sua View Controller e desative a opção [ Adjust Scroll View Insets ] caso sua
UITableView tenha uma margem superior desnecessária.
Vamos adicionar uma UITableView à nossa view.
Você pode está se perguntando sobre o por quê não usar a Table View Controller
ao invés de adicionar uma UITableView a View Controller.
A UITableView foi criada, porém, ela ainda não possui nenhuma célula para que possamos
inserir dados nela. Células conhecidas como UITableViewCell.
Selecione a UITableView e clique no botão Inspector no canto superior direito do
Xcode e adicione um protótipo de célula para um conteúdo dinâmico.
Aqui indicamos a ViewController que sua UITableView terá células sendo criadas
dinamicamente de acordo com este protótipo de célula UITableViewCell. Mais a frente,
iremos criar células customizadas com imagens, textos e etc.
Quando você selecionar a UITableViewCell e clicar no Inspector você poderá
mudar o estilo da célula. O Xcode nos fornece 5 opções de estilo para a UITableViewCell.
● Custom
● Basic
● Right Detail
● Left Detail
● Subtitle
Pra começar, vamos escolher o estilo subtitle da UITableViewCell.
PASSO #3: CRIANDO O MODEL VIEW CONTROLLER
(M-V-C)
Nossa tabela precisa de dados para serem listados. Mas antes de criar os dados, vamos
adicionar algumas imagens do nosso aplicativo (game store). Para adicionar, vamos selecionar a
pasta Assets.xcassets. Clique no sinal de "mais" [ + ] e clique em New Image
Set.
Selecione no seu Finder as imagens dos produtos (jogos digitais) e adicione ao pacote de
imagens no xcode.
Imagens 2x são utilizadas para dispositivos de alta resolução (retina).
Para criar a View Controller que será responsável por "gerenciar" nossa view e os
dados (model), basta usar as teclas [ cmd + N ], escolher uma nova classe Cocoa Touch
Class.
Agora que a view sabe que é sua controladora, vamos construir uma referência da nossa
UITableView no código swift para que possamos manipular esse componente via código.
Quando selecionar a (no ícone amarelo em cima da controller) ViewController
podemos abrir a classe em uma nova perspectiva de janela e conectar os pontos (view e
controller).
Aqui acontece a "mágica" do Xcode. Muita atenção aqui! Você deve selecionar a
UITableView,segurar a tecla Ctrl, clicar e arrastar o mouse para dentro do código
swift e BOOM! Agora é possível criar um IBOutlet (uma referência) da UITableView.
Dê um nome a nova variável. Neste ponto a ViewController sabe qual é o componente (leia-se
view) que deve ser manipulada.
@IBOutlet weak var tableView: UITableView!
Sempre que um IBOutlet é criado e conectado com a View, sua referência com a View é
garantida quando uma pequena "bolinha" é exibida.
Vamos retomar a UITableViewCell e adicionar um identificador para ela. Logo, quando
estivermos trabalhando dentro do Swift, podemos pegar essa view dentro do código através de
seu Identifier. Chamaremos nosso identificador de GameCell.
Chegou a hora de criar os dados!
Para manter o foco desse material que é a UITableView,vou mostrar um arquivo Model
Fake pronto com os dados necessários para exibir na tabela. Lembre-se que os dados podem
vir de vários ambientes, seja um arquivo, um JSON via HTTP, um XML do webservice,
whatever…
Esse arquivo possui uma Struct de Game e uma Struct que lista esses Games com um método
estático. Essa é a forma mais rápida de se construir dados fakes para podermos utilizar em
nossos controllers.
//
// Games.swift
// gamestore
//
// Created by Tiago Aguiar on 3/29/17.
// Copyright © 2017 Code Spartan. All rights reserved.
//
import Foundation
struct Game {
var name: String
var desc: String
var imageName: String
}
struct Games {
static func getAllGames() -> [Game] {
return [
Game(name: "Resident Evil 7", desc: "horror game",
imageName: "resident_evil_7"),
Game(name: "The Legend of Zelda Skyward", desc: "adventure
game", imageName: "legend_of_zelda_sky"),
Game(name: "God of War 3", desc: "adventure game",
imageName: "god_of_war_3"),
]
}
}
Ok! Agora que temos nossa camada Model definida, vamos a Controller e fazer a
UITableView ler esses dados.
Primeiro, vamos recordar como está a classe neste momento.
class GameViewController: UIViewController {
@IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
Temos apenas nossa view com uma referência weak nomeada tableView.
Os métodos viewDidLoad e didReceiveMemoryWarning são executadas no ciclo de vida da View
Controller. Não iremos entrar em detalhes neste momento.
Para que o aplicativo liste os jogos que, em tese, cadastramos, vamos fazer os seguintes passos:
1. Declarar a variável de games.
2. Criar uma extension da GameViewController
3. Implementar o protocol UITableViewDataSource que será responsável por observar
os eventos que acontece na tableView como construir novas células.
4. Definir o número de seções que a tabela terá
5. Definir o número de linhas por seção
6. Adquirir o objeto TableViewCell e atribuir os dados da model.
7. Dizer a tableView qual será a classe responsável por observar o protocol
UITableViewDataSource
Lembra do identificador que colocamos na UITableViewCell?
Agora iremos utilizar no método:
let cell = tableView.dequeueReusableCell(withIdentifier:
"GameCell")!
Dessa forma, garantimos que todas as vezes que houver a necessidade de uma rolagem na
tabela através do scrolling podemos reutilizar o objeto, evitando a criação de novos objetos para
cada célula exibida na tela. Logo, a memória é desalocada e objetos reutilizados sempre que
necessário. Esse gerenciamento de objetos TableViewCell é feito automaticamente pela
plataforma.
Execute a aplicação e veja o resultado final. É eu sei… não ficou um aplicativo fantástico no
estado da arte (ainda) mas, podemos entender o core de como funciona uma tableView.
Em resumo, criamos uma view, conectamos com a view controller com esta view e com o
model e por fim, fizemos um dataSource que construi células e atribui os dados em cada célula.
PASSO #4: SECTIONS E ROWS NA UITABLEVIEW
Agora que temos uma table construída, adicionar seções com cabeçalho fica muito mais fácil.
A primeira coisa a se fazer é adicionar mais produtos. Neste caso, eu adicionei a seguinte
estrutura de imagens e jogos.
Console: PS4
- Titulo: Resident Evil 7
- God of War 3
- Outlast
Console: Wii
- The Legend of Zelda Skyward
- Super Mario Bros.
Console: Xbox 360
- Gears of War
Segundo passo é modificar nossos arquivos .swift:
1. Adicionar um array de game array [[Game]] no model
2. Adicionar um array de String com os Titulos da seção [ String ] no model
3. Adicionar a variável: var titles = Games.getAllTitle()
4. Método numberOfSections: retornar titles.count
5. Método numberOfRowsInSection: retornar games[section].count
6. Adicionar Método titleForHeaderInSection: retornar titles[section]
7. Trocar games[indexPath.row] para
games[indexPath.section][indexPath.row]
Veja a seguir o código completo do Model e ViewController e o resultado final da nossa tabela
com seções.
//
// Games.swift
// gamestore
//
// Created by Tiago Aguiar on 3/29/17.
// Copyright © 2017 Code Spartan. All rights reserved.
//
import Foundation
struct Game {
var name: String
var desc: String
var imageName: String
}
struct Games {
static func getAllGames() -> [[Game]] {
return [
[
Game(name: "Resident Evil 7", desc: "horror game",
imageName: "resident_evil_7"),
Game(name: "God of War 3", desc: "adventure game",
imageName: "god_of_war_3"),
Game(name: "Outlast", desc: "horror game", imageName:
"outlast"),
],
[
Game(name: "The Legend of Zelda Skyward", desc:
"adventure game", imageName:
"legend_of_zelda_sky"),
Game(name: "Super Mario Bros.", desc: "adventure game",
imageName: "super_mario_bros")
],
[
Game(name: "Gears of War", desc: "action game",
imageName: "gears_of_war"),
]
]
}
import UIKit
tableView.dataSource = self
}
cell.textLabel?.text = games[indexPath.section][indexPath.row].name
cell.detailTextLabel?.text = games[indexPath.section][indexPath.row].desc
cell.imageView?.image = UIImage(named: games[indexPath.section][indexPath.row].imageName)
return cell
}
}
PASSO #5: CUSTOM UITABLEVIEWCELL - O PODER PARA
CRIAR CÉLULAS DO JEITO QUE VOCÊ QUISER!
Vamos entrar na parte mais divertida e benéfica da UITableView, criar suas próprias
células e deixar a sua arte fluir pelo aplicativo.
Aqui vamos aplicar um pouco mais de Design no aplicativo e fazer com que os nossos produtos
(jogos digitais) tenha uma melhor apresentação.
Este passo é simples, mas não é fácil. Logo, é de suma importância ter a total atenção nos
próximos passos.
Antes de mais nada, vamos mudar o estilo da nossa UITableViewCell para custom.
Aumente o tamanho da célula na storyboard para começar o Design.
Adicione uma ImageView com constraint para aplicar o AutoLayout.
Você terá constraints c om Top, Left = 0. Width, Height = 100.
Adicione mais 3 UILabel que servirá para mostrar o título do jogo, o tipo e a descrição.
Você terá constraints com Top, Left, Right = 8 para cada UILabel.
Para que a imagem mantenha a proporção mesmo adicionadno uma constraints de
largura e altura = 100, adicione o content mode para aspect fit.
Altere a fonte de UILabel das de acordo com sua preferência.
Crie a classe GameCell da mesma forma que criou a primeira ViewController [ cmd + n ].
Você terá uma: class GameCell: UITableViewCell.
Lembra que para nossas classes se conectarem com a view precisamos referênciá-las na
storyboard e depois, adicionar os @IBOutlet?
Esse é o próximo passo.
-
Ainda não temos o atributo type e desc definidos no nosso model.
Altere a Struct Game.
//
// Games.swift
// gamestore
//
// Created by Tiago Aguiar on 3/29/17.
// Copyright © 2017 Code Spartan. All rights reserved.
//
import Foundation
struct Game {
var name: String
var type: String
var imageName: String
var desc: String
}
struct Games {
static func getAllGames() -> [[Game]] {
return [
[
Game(name: "Resident Evil 7", type: "horror game", imageName: "resident_evil_7",
desc: "O título coloca o jogador na pele de Ethan Winters, que deve ir em
busca de sua namorada desaparecida – isso depois que ela própria enviou uma
misteriosa mensagem, após anos sem dar notícias. Ao chegar ao local, o
personagem precisa lidar com uma família um tanto estranha e ameaçadora."),
Game(name: "God of War 3", type: "adventure game", imageName: "god_of_war_3", desc:
"Quando God of War 3 foi anunciado em 2008 para PlayStation 3, muito se
falou sobre as principais inovações nas mecânicas. O God of War 2 apresentou
uma história fantástica, apesar da mesma jogabilidade do primeiro episódio
da saga."),
Game(name: "Outlast", type: "horror game", imageName: "outlast", desc: "Outlast foi
lançado este mês para PC, trazendo uma experiência de horror bem além da
concorrência. A equipe da Red Barrels, formada por profissionais
responsáveis por jogos como Prince of Persia: Sands of Time, Assassin’s
Creed e Splinter Cell, conseguiu atingir um nível impressionante de tensão
no game, mas isso não quer dizer que Outlast não possua falhas"),
],
[
Game(name: "The Legend of Zelda Skyward", type: "adventure game", imageName:
"legend_of_zelda_sky", desc: "E mais uma vez, a Nintendo nos presenteia com
um belíssimo jogo, digno de ser um “Zelda”, acessível para iniciantes,
indispensável para os fãs e com o acréscimo de elementos que, possivelmente,
definirão o futuro da série"),
Game(name: "Super Mario Bros.", type: "adventure game", imageName:
"super_mario_bros", desc: "Desde o lançamento do Nintendo 3DS os fãs aguardam
por um game do Mario com uma pegada mais “clássica”, lembrando os jogos mais
antigos da franquia. O game Super Mario 3D Land foi muito bom, mas tinha
pouco daquele Mario “2D” que a grande parte dos jogadores cresceu jogando, e
é com New Super Mario Bros")
],
[
Game(name: "Gears of War", type: "action game", imageName: "gears_of_war", desc:
"Muitos jogadores de todo o planeta procuram somente diversão em seus jogos,
não importando qual gênero ou estilo. Afinal, essa é a proposta principal de
todos os videogames: entreter. Muitos games de esporte, luta, ação ou tiro
conseguem facilmente prender os jogadores por horas em frente à televisão.
"),
]
]
}
import UIKit
}
Terminado o trabalho na GameCell, coloque a aplicação para executar e veja o resultado.
Você está quase lá! Perceba que a descrição ficou cortada, isto é, tem apenas uma linha e o
título do Zelda, por exemplo, ficou com reticências. Vamos corrigir isso.
Na storyboard, selecione a última label e diminui o número de linhas para 0.
Agora adicione uma constraint bottom nesta última label da mesma forma que fazemos em
outros componentes. Nesse momento, você pode se deparar com alguns conflitos de
constraint. Para resolvê-los, vamos alterar as prioridades das constraints.
Altere as prioridades de acordo com a imagem abaixo sendo que:
Label 1 ( title ) ->
content hugging priority
horizontal: 251
vertical: 251
content compression resistance priority
horizontal: 750
vertical: 750
Label 2 ( type ) ->
content hugging priority
horizontal: 251
vertical: 252
content compression resistance priority
horizontal: 750
vertical: 750
Label 3 ( desc ) ->
content hugging priority
horizontal: 251
vertical: 252
content compression resistance priority
horizontal: 750
vertical: 751
Uma outra forma de corrigir os conflitos é solicitar ao próprio Xcode que defina as prioridade
para você. Quando ocorre um erro de constraint o Xcode mostra uma pequena bola vermelha
onde você pode clicar e solicitar a melhor opção pelo IDE.
Corrigido a View, em tese, ele crescerá automaticamente porque agora não definimos um
número de linhas maior que 0.
Antes de executar você deve avisar que sua table view terá um ajuste dinamico no tamanho
das linhas. Logo, adicione o seguinte código ao viewDidLoad.
tableView.estimatedRowHeight = tableView.rowHeight
tableView.rowHeight = UITableViewAutomaticDimension
//
// GameViewController.swift
// gamestore
//
// Created by Tiago Aguiar on 3/29/17.
// Copyright © 2017 Code Spartan. All rights reserved.
//
import UIKit
tableView.dataSource = self
tableView.estimatedRowHeight = tableView.rowHeight
tableView.rowHeight = UITableViewAutomaticDimension
}
cell.game = games[indexPath.section][indexPath.row]
return cell
}
}
Legal! Agora só falta ajustar o título para caber na célula.
Você pode corrigir isso alterando o atributo Autoshrink na label.
Com esse parâmetro, você indica ao aplicativo para usar a fonte padrão, porém, se não for
possível exibir o texto por completo, tente o valor minimo definido (Minimum Font Size).
Alteramos para 9 e o resultado é o seguinte:
Agora você pode criar views customizadas para a sua tableview.
Nesse momento, você pode ter tido diversas dúvidas e até dificuldade. Mas isso é
completamente normal. Crie outras tabelas, customize diferente, faça você as alterações
necessárias para aprender mais. O que eu fiz aqui foi destrinchar do que uma tableview é capaz
e como usar ela conectando Design e dados. Cabe a você otimizar e melhorar as suas
habilidades como desenvolvedores iOS.
Mas ainda não acabou! Quero te ensinar mais!
Os próximos passos são ordenação e exclusão de registros na tabela.
Vamos começar.
PASSO #6: EXCLUSÃO DE CÉLULAS NA TABLEVIEW
Há duas maneiras de excluir um registro em uma tabela. Arrastando o registro para o lado e
clicando em Delete ou em Editar na toolbar.
Para adicionar o botão na toolbar você precisará usar uma variável chamada
editButtonItem.
self.navigationItem.rightBarButtonItem = editButtonItem
Adicione o pedaço de código acima no método viewDidLoad.
Como não estamos utilizando uma UITableViewController precisamos indicar que
nossa tableView agora será editável. O seguinte método deve estar na sua viewController.
override func setEditing(_ editing: Bool, animated: Bool) {
super.setEditing(editing, animated: animated)
self.tableView.setEditing(editing, animated: animated)
}
Na extension onde temos nosso DataSource, adicione o seguinte código:
func tableView(_ tableView: UITableView, commit editingStyle:
UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
games[indexPath.section].remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .automatic)
}
}
Este bloco de código irá ser executado quando houver uma ação na tableView como edição ou
exclusão. Nesse caso, além de remover do objeto tableView, também removemos do array
games o registro.
PASSO #7: REORDENAÇÃO DE CÉLULAS NA TABLEVIEW
Se você quiser reordenar os elementos na tabela, você precisará adicionar ao seu método
viewDidLoad um novo protocol conhecido como Delegate.
Basta adicionar a seguinte linha de código e adicionar à extension a
UITableViewDelegate
tableView.delegate = self
extension GameViewController: UITableViewDataSource,
UITableViewDelegate {
}
Feito isso, nossa tabela terá um observer responsável por escutar eventos na tabela. Agora,
vamos indicar em quais células podem ocorrer o evento de ordenação ( canMoveRowAt ).
Como queremos reordernar todos os elementos em de cada seção, o retorno deste método
será sempre true.
func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
return true
}
Outra coisa que faremos uma verificação é não deixar que uma célula de uma seção possa ser
movida para dentro de outra seção, pois isso não faz sentido para este nosso aplicativo que lista
jogos de acordo com o console específico.
func tableView(_ tableView: UITableView, targetIndexPathForMoveFromRowAt sourceIndexPath:
IndexPath, toProposedIndexPath proposedDestinationIndexPath: IndexPath) -> IndexPath {
if sourceIndexPath.section != proposedDestinationIndexPath.section {
return sourceIndexPath
} else {
return proposedDestinationIndexPath
}
}
Perceba que nesse método acima, sempre que um elemento sobrescreve outro elemento
quando seguramos a célula com o touch e arrastamos ela para baixo por exemplo, nós
verificamos se a seção é a mesma. Caso seja diferente, retornamos o mesmo indice (indexPath)
para evitar a reordenação neste caso.
func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to
destinationIndexPath: IndexPath) {
if sourceIndexPath != destinationIndexPath {
let game = games[sourceIndexPath.section][sourceIndexPath.row];
games[sourceIndexPath.section].remove(at: sourceIndexPath.row)
games[sourceIndexPath.section].insert(game, at: destinationIndexPath.row)
tableView.moveRow(at: sourceIndexPath, to: destinationIndexPath)
tableView.reloadData()
}
}
Com a validação de seção ok, o método acima é executado e removemos tanto da tabela
quanto do array o elemento e, colocamos ele na posição de destino. Ao final, daremos um
reloadData na tabela para garantir que as células possam ser reconstruídas novamente.
PASSO #8: STATIC CELL E UM DESAFIO PARA VOCÊ
Você já é capaz de listar dados em qualquer aplicativo e ainda de uma forma elegante e
customizada!
A partir de agora quero propor um desafio para você. Dessa forma, poderá colocar em prática
tudo o que já aprendeu até aqui, descobrir mais obstáculos e melhorar a suas habilidades como
desenvolvedor iOS.
Até esse momento, criamos uma lista de dados dinâmicos, que cresce e diminui de acordo com
nossos arrays. Existe um outro tipo de célula conhecida como Static Cell que utilizamos criar
telas de detalhes de um modelo de dados como, por exemplo, o nosso jogo digital em si.
O desafio é: Criar uma TableViewController com uma Static Cell para mostrar a imagem e a
descrição do produto ao clicar em cada item na TableView principal.
Pra fazer isso, você precisará criar a view em si, controllers e o método prepareForSegue, para
transportar o seu objeto Game entre as controllers.
Para te ajudar, mas sem resolver o desafio, irei colocar as classes para que você possa ler o
código e revisá-lo. É como se eu estivesse mostrando a resultado de uma conta matemática
sem resolver o problema. :-)
Dica 1: Main.storyboard
GameViewController:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let gameDetailVC = segue.destination as! GameDetailViewController
if let gameCell = sender as? GameCell {
gameDetailVC.game = gameCell.game
}
}
//
// GameViewController.swift
// gamestore
//
// Created by Tiago Aguiar on 3/29/17.
// Copyright © 2017 Code Spartan. All rights reserved.
//
import UIKit
self.navigationItem.rightBarButtonItem = editButtonItem
tableView.dataSource = self
tableView.delegate = self
tableView.estimatedRowHeight = tableView.rowHeight
tableView.rowHeight = UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
games[indexPath.section].remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .automatic)
}
}
if sourceIndexPath != destinationIndexPath {
let game = games[sourceIndexPath.section][sourceIndexPath.row];
games[sourceIndexPath.section].remove(at: sourceIndexPath.row)
games[sourceIndexPath.section].insert(game, at: destinationIndexPath.row)
tableView.moveRow(at: sourceIndexPath, to: destinationIndexPath)
tableView.reloadData()
}
}
cell.game = games[indexPath.section][indexPath.row]
return cell
}
}
//
// GameDetailViewControllerTableViewController.swift
// gamestore
//
// Created by Tiago Aguiar on 4/8/17.
// Copyright © 2017 Code Spartan. All rights reserved.
//
import UIKit
tableView.estimatedRowHeight = 44.0
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if indexPath.section == 0 {
return 250.0
}
return UITableViewAutomaticDimension
}
}
CONSIDERAÇÕES FINAIS
Agora você sabe que 20% dos seus esforços deve ser direcionados para o TableView porque
ela é responsável por estar em 80% do aplicativo. Logo, criar aplicativos iOS é bem mais
simples do que você imaginava.
Você só precisa dominar a storyboard e conectar views e controllers usando os métodos que a
própria Apple disponibiliza em suas classes.
Seja o facebook, o Instagram, Whatsapp, Spotify ou Twitter, você poderá criar algo similar e até
melhores que estes, basta entender os principios por trás desses grandes apps e você verá que
eles são realmente simples.
ACESSE O CÓDIGO FONTE COMPLETO
https://www.dropbox.com/s/iyra73hefcl6guj/gamestore.zip?dl=0
ACESSE MEU CANAL NO YOUTUBE
https://goo.gl/PBDFKU
ACESSE MINHA PÁGINA NO FACEBOOK
https://goo.gl/o5QMlp
ACESSE MEU WEBSITE OFICIAL
https://goo.gl/iDlRqE