Vinicius Quaiato

{tecnologia, conceitos, negócios, idéias, práticas, .NET, ruby, osx, ios e algo mais}

Usando UITableView em apps iOS


Muitas aplicações fazem uso de listagens de dados e no iOS vamos usar uma(ou mais) instância de UITableView para realizar este trabalho.

Basicamente quando falamos de iOS e table view estamos falando de um controle com uma única coluna e uma lista de dados (o motivo de haver apenas uma coluna é o tamanho das telas).

Para ilustrarmos um primeiro uso de UITableView vamos incrementar o projeto de Gastos de rua para exibir uma listagem dos gastos realizados. Faremos algumas alterações para isso:

  1. Criar um novo View Controller e um arquivo nib para nossa listagem
  2. Adicionar um UITableView a este nib para exibir os valores
  3. Exibir os valores na UITableView

Criando um novo ViewController

Vamos adicionar um novo ViewController em nossa aplicação, chamado de ListaDeValoresViewController, assim como vemos abaixo:

Feito isso vamos adicionar um botão à nossa tela para que possamos exibir nossa nova tela:

Vamos então adicionar um import em nosso ViewController.m para que possamos chamar a nova tela:

#import "ListaDeValoresViewController.h"

Agora vamos criar uma IBAction vinculada ao nosso botão que fará a chamada para a nova tela.

ViewController.h:

- (IBAction)verListaDeValores:(id)sender;

ViewController.m:

- (IBAction)verListaDeValores:(id)sender {
    ListaDeValoresViewController* lista = [[ListaDeValoresViewController alloc]
                                            initWithNibName:@"ListaDeValoresViewController"
                                            bundle:nil];

    [self presentViewController:lista animated:YES];
}

Feito isso se rodarmos nossa app e clicarmos no botão veremos uma nova tela branca. A mágica aqui fica por conta da chamada presentViewController que como podemos imaginar apresenta um view controller e no nosso caso o view controller que carrega a lista de valores. Nada de outro mundo certo?

Utilizando UITableView

Na nossa view ListaDeValores.xib vamos adicionat um UITableView, conforme abaixo:

Basta arrastar e redimensionar o controle.

O segredo aqui é que um UITableView precisa de alguém que implemente dois protocolos: UITableViewDelegate e UITableViewDataSource Basicamente estes caras são responsáveis por gerenciar uma série de aspectos de um UITableView e seus dados. Mas nós começaremos com o básico, suficiente para exibir nossos dados na listagem.

Vamos então adicionar os protocolos em nosso ListaDeValoresViewController.h e além disso vamos criar um construtor que receba nosso objeto gastos, teremos então esse código:

#import <UIKit/UIKit.h>
#import "Gastos.h"

@interface ListaDeValoresViewController : UIViewController<UITableViewDelegate, UITableViewDataSource>
{
    Gastos* gastos;
    Locale* locale;
    NSNumberFormatter* formatter;
}
- (IBAction)voltar:(id)sender;
- (id) initWithNibAndGastos:(NSString*)nib : (Gastos*)passedGastos;
@end

Tranquilo, certo? Tudo que fazemos aí é criar uma variável de instância do tipo Gastos, um formatter e locale para exibir tudo bacana e criamos um método que inicializará nossa classe com o nome do arquivo nib e os gastos recebidos: initWithNibAndGastos.

Agora vamos implementar alguns métodos no ListaDeValoresViewController.m

 1 - (id) initWithNibAndGastos:(NSString *)nib :(Gastos *)passedGastos{
 2     self = [super initWithNibName:nib bundle:nil];
 3     gastos = passedGastos;
 4 
 5     locale = [[NSLocale alloc] initWithLocaleIdentifier:@"pt_BR"];
 6     formatter = [[NSNumberFormatter alloc]init];
 7     [formatter setLocale: locale];
 8     [formatter setNumberStyle:NSNumberFormatterCurrencyStyle];
 9 
10     return self;
11 }
12 
13 //Métodos para TableView
14 - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
15     return @"Valores gastos";
16 }
17 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
18 {
19     return [gastos totalDeGastos];
20 }
21 
22 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
23 {
24     static NSString *CellIdentifier = @"Cell";
25 
26     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
27     if (cell == nil) {
28         cell = [[UITableViewCell alloc]
29                                      initWithStyle:UITableViewCellStyleDefault
30                                      reuseIdentifier:CellIdentifier];
31     }
32 
33     cell.textLabel.text = [formatter stringFromNumber:[gastos gastoAtIndex:indexPath.row]];
34 
35     return cell;
36 }

Vamos lá: das linhas 1 até 11 o que fazemos é instanciar nosso view controller com o nome do nib informado e o objeto gastos passado. Também inicializamos um formatter para deixar nosso números bacanas na listagem (já vimos sobre isso aqui). Este método comporta-se como um construtor retornando a si mesmo após chamar um método da classe base.

Nas linhas 14 até 16 apenas informamos um título para o header da nossa seção (lembre-se que temos apenas uma).

Nas linhas 17 até 20 o que fazemos é informar quantas linhas teremos nesta seção da nossa table. Um UITableView pode possuir diversas seções, por enquanto temos apenas uma então informamos o total de gastos em nosso objeto.

Nas linhas 22 até 36 é onde de fato criamos as células da nossa table view. O que precisamos entender aqui é que esse é um padrão para otimizar o uso de memória. Entenda que se só conseguimos mostrar umas 5 rows de cada vez em uma tela não é preciso criar todas as rows da table. Então as rows são reaproveitadas e teremos apenas 5 ao todo. Assuma que aí apenas a linha 33 é o que muda. Nesta linha formatamos o texto que será exibido na row.

Antes de finalizarmos vamos vincular o datasource e o delegate de nossa table view ao nosso file owner (ou seja o view controller onde implementamos tudo):

Feito! Agora quando adicionarmos alguns valores na nossa tela principal e clicarmos no botão para vermos a listagem teremos algo assim:

Resumindo

Novamente parece que tivemos um mega trabalho quando na verdade os passos foram bem simples e tranquilos se você ler e tentar fazer o mesmo com calma.

Com isso estamos conseguindo dar uma cara mais interessante para nossa simples aplicação e já começamos a abrir caminho para os próximos passos como por exemplo: navegação.

Sem dúvida alguma essa já é quase uma aplicação que pode nos ajudar: se pensarmos em ao invés de um array de valores criarmos um dicionário com data:[valores] a coisa começa a ficar mais interessante.

Tente ler a documentação dos protocolos relacionados com UITableView(UITableViewDelegate e UITableViewDataSource) e verá que não é nenhum bicho de outro mundo.

https://github.com/vquaiato/ios-blog-samples/tree/master/somatorioDeContasTableView

Abração,

Vinicius Quaiato.

Voltar

Fork me on GitHub