Depois de estudar por algumas vezes a programação para a plataforma iOS, resolvi escrever uma série de posts sobre o assunto. Como eu já fiz um "Hello World" e um exemplo básico de tratamento de evento (aqui e aqui respectivamente) vou começar falando do componente UITableView. Esse componente serve para exibir informações em uma lista.
Vamos começar criando um novo projeto no XCode. Selecione File > New > New Project... Na janela que for exibida, selecione Empty Application. Depois preencha os campos conforme a imagem abaixo.
#import <UIKit/UIKit.h> @interface NGAppDelegate : UIResponder <UIApplicationDelegate> @property (strong, nonatomic) UIWindow *window; @property (strong, nonatomic) UINavigationController *navegador; @endNo arquivo .m já foram criados alguns métodos pelo template do XCode, mas só vamos mexer no application:didFinishLaunchingWithOptions.
#import "NGAppDelegate.h" #import "ListagemViewController.h" @implementation NGAppDelegate @synthesize window = _window; @synthesize navegador; - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)opts { self.window = [[UIWindow alloc] initWithFrame:[ [UIScreen mainScreen] bounds]]; ListagemViewController *lista = [[ListagemViewController alloc] init]; navegador = [[UINavigationController alloc] initWithRootViewController:lista]; self.window.backgroundColor = [UIColor whiteColor]; self.window.rootViewController = navegador; [self.window makeKeyAndVisible]; return YES; }Nesse método instanciamos a nossa tela, e em seguida instanciamos o UiNavigationController passando a nossa tela como tela "raiz", ou seja, a principal. Depois associamos o UINavigationController ao objeto UIWindow, que representa a tela do aparelho.
Neste ponto, você já pode mandar rodar a aplicação, mas não teremos nada para listar. Então vamos a implementação da nossa listagem. No arquivo ListagemViewController.h, declare um array chamado nomes, conforme abaixo:
#import <UIKit/UIKit.h> @interface ListagemViewController : UITableViewController { NSArray *nomes; } @endComo podemos observar, nossa classe herda de UITableViewController. Essa classe implementa dois protocolos (que em Java são interfaces) UITableViewDelegate e UITableViewDataSource. O primeiro trata de eventos disparados pela lista e o segundo define métodos que irão prover informações para a lista. Ao abrirmos o arquivo, podemos notar que temos vários métodos implementados, por isso só vou colocar no código abaixo os métodos que teremos que modificar.
#import "ListagemViewController.h" @implementation ListagemViewController #pragma mark - View lifecycle - (void)viewDidLoad { [super viewDidLoad]; self.navigationItem.title = @"Listagem"; nomes = [NSArray arrayWithObjects: @"Nelson", @"Glauber", @"Vasconcelos", @"Leal", nil]; } // ... um monte de métodos :) #pragma mark - Table view data source - (NSInteger)numberOfSectionsInTableView: (UITableView *)tableView { return 1; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return nomes.count; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; } cell.textLabel.text = [nomes objectAtIndex:indexPath.row]; return cell; } @endNo método viewDidLoad, inicializamos nossa lista de nomes e alteramos o título da tela. Já no método numberOfSectionsInTableView retornamos a quantidade de sessões que a lista terá. As sessões servem para agrupar opções de uma lista, mas no nosso caso, teremos apenas uma. No método tableView:numberOfRowsInSection retornamos quantas linhas têm cada sessão, como só temos uma, retornamos a quantidade de itens do nosso array de pessoas.
O último método que alteramos foi o tableView:cellForRowAtIndexPath, ele cria um objeto UITableViewCell para cada item da lista. Para evitar a criação de muitos objetos ele tenta reaproveitar linhas que não estejam mais visíveis na tela. Isso é feito no método dequeueReusableCellWithIdentifier:CellIdentifier. Caso não haja uma linha pra reciclar, criamos uma UITableViewCell com o estilo padrão (UITableViewCellStyleDefault). Em seguida, alteramos o texto da UITableViewCell (que internamente contém um UILabel) utilizando o nosso array de nomes. Para obter a posição a ser exibida, utilizamos a propriedade row o parâmetro indexPath. Pronto! Basta rodar nossa aplicação, e o resultado deverá ficar como abaixo:
Abra o DetalheViewController.xib e arraste um Label para a tela e faça os ajustes de posicionamento e tamanho que desejar. Em seguida, vamos criar o IBOutlet para esse label: clique com o botão direito sobre o botão, e em Referencing Outlets clique em New Referencing Outlet e arraste para o arquivo .h.
#import <UIKit/UIKit.h> @interface DetalheViewController : UIViewController @property (weak, nonatomic) IBOutlet UILabel *txtDetalhe; @property (strong, nonatomic) NSString *texto; @end
#import "DetalheViewController.h" @implementation DetalheViewController @synthesize txtDetalhe, texto; - (void)viewDidLoad { [super viewDidLoad]; txtDetalhe.text = texto; }Estamos quase lá. Agora volte ao arquivo ListagemController.m implemente o método tableView:didSelectRowAtIndexPath que é o método chamado quando clicamos em um item da lista.
// Adicionar import no começo do arquivo #import "DetalheViewController.h" - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { DetalheViewController *detailViewController = [[DetalheViewController alloc] initWithNibName: @"DetalheViewController" bundle:nil]; detailViewController.texto = [nomes objectAtIndex:indexPath.row]; [self.navigationController pushViewController: detailViewController animated:YES]; }O método acima instancia nosso DetalheViewController passando o arquivo *.xib (sem a extensão), em seguida atribui a propriedade texto e utiliza o navigationController (que criamos no AppDelegate) para exibir a tela. O resultado pode ser visto abaixo: