Escolar Documentos
Profissional Documentos
Cultura Documentos
Fundamentos
Apostila do Aluno
Fundamentos
Apostila do Aluno
Copyright © Instituto de Artes Interativas
Todos os direitos reservados. Esse material não pode ser copiado, fotocopiado, reproduzido,
traduzido ou convertido em qualquer forma eletrônica ou legível por meio, em parte ou no todo,
sem a aprovação prévia por escrito do Instituto de Artes Interativas.
Elaboração do Conteúdo
André Baldi
Diagramação
Samuel Sanção de Moura
Edição nº1
Novembro /2011
iOS Fundamentos 3
iOS: Fundamentos
Sobre o iai?
A história do iai?
O iai? Instituto de Artes Interativas foi fundada em março de 2009 com cursos de desenvolvimento
de aplicativos para iOS contando com uma proposta inovadora e atualizada, nestes últimos 3 anos
tivemos mais de 2000 alunos em nossos cursos.
Dessa forma, procuramos uma equipe coesa, criativa, e eficiente para desenvolver soluções e
inovações no mundo das artes interativas e educação.
Galeria
Exposição de artes e locação
para eventos corporativos
Escola Produtora
Cursos práticos, rápidos Desenvolvimento de
e objetivos aplicativos móveis
Na área educacional, O Iai? se destaca na oferta cursos com aprendizagem rápida, presencial e a
distância, contando com know how em sistemas móveis como iPhone SDK, Android SDK e Windows
phone 7, além de Lógica de programação, design, interfaces entre outros. Os cursos do iai? são
voltados para profissionais que buscam a capacitação por meio do conhecimento e domínio de
novas ferramentas tecnológica com cursos práticos e objetivos aonde aprendem produzindo.
iOS Fundamentos 5
Como encontrar o iai?
O Iai? conta com várias formas de se comunicar com o seus clientes e amigos, use a forma mais
fácil e prática para você.
iai.art.br
instituto de artes interativas
@iaibrasil
iai.art.br/clube-iai.html
iOS Fundamentos 6
Outros cursos do iai?
IOS SDK
Programação para o sistema operacional da Apple
ANDROID SDK
Programação para o sistema operacional da Google
Lógica de programação
Conceitos Básicos de programação
Design
O objetivo do curso é ensinar a montar um projeto de design utilizando como plataforma um
aplicativo para iPhone.
Interface
O curso é focado nas guias da Apple e pretende discutir as melhores formas de interface.
Games
Focamos em estratégias e técnicas para desenvolvimento de jogos para o Iphone, demonstrando o
funcionamento do Cocos2D.
Windows Phone 7
Venha desenvolver para o mais novo sistema operacional da Micrsoft que promete mexer com
Mercado de tecnologia.
iOS Fundamentos 7
iOS: Fundamentos
Sumário
Sumário
Capítulo 1
1.1 NSObject 14
1.2 NSString 14
1.3 NSLog 15
1.4 Hello World! 16
1.5 UIView 21
1.6 Exemplo de UIView 23
1.7 UILabel 25
1.8 Exemplo de UILabel 26
1.9 UIButton 28
1.10 Exemplo de UIButton 31
Capítulo 2
2.1 UIViewController 36
2.2 Exemplo de UIViewController 37
2.3 XIB e Storyboard 42
2.4 Exemplo de Storyboard 43
Capítulo 3
3.1 IBOutlet 47
3.2 Exemplo de IBOutlet 47
3.3 IBAction 52
iOS Fundamentos 9
Sumário
4.5 Delegate 71
Capítulo 5
5.1 DataSource 78
5.2 UIPickerView 78
5.3 NSArray 80
Capítulo 6
6.1 UIScrollView 86
iOS Fundamentos 10
Sumário
6.2 UIPageControl 87
6.3 Exemplo 87
6.4 Zoom com UIScrollView 93
6.5 Exemplo de UIScrollView com zoom 93
Capítulo 7
7.1 Modal View Controller 98
7.2 Exemplo 98
7.3 Modal View Controller via código 103
7.4 Exemplo de Modal View Controller via código 104
7.5 @property e @synthesize 108
7.6 Exemplo de @property 110
Capítulo 8
8.1 UINavigationController 116
8.2 Exemplo de UINavigationController 117
8.3 Exemplo de UINavigationController no Storyboard 124
8.4 UITableView e UITableViewCell 128
8.5 Exemplo de UITableView 129
8.6 UITableViewController 136
8.7 Master Detail Application 137
iOS Fundamentos 11
Sumário
Capítulo 9
9.1 NSDictionary 139
9.2 Exemplo de NSDicitonary 139
9.3 Arquivos de Property List 147
9.4 Exemplo de plist 147
9.5 Objetos mutáveis 152
9.6 Edição de tabelas 154
9.7 Exemplo de edição de tabela 155
9.8 Persistência de dados 160
9.9 Exemplo de persistência de dados 160
Capítulo 10
10.1 UITabBarController 166
10.2 Exemplo de UITabBarController 168
10.3 Tabbed Application 173
10.4 Imagens padrões e Retina Display 173
10.5 Exemplo 175
10.6 Arquivo Info.plist 178
iOS Fundamentos 12
iOS: Fundamentos
Capítulo 1
1
1.1 NSObject
• alloc: cria uma nova instância da classe, mas que ainda não pode ser usada.
1.2 NSString
A classe NSString estende a classe NSObject e define um array de caracteres,
ou seja, uma string. Pode parecer um pouco semelhante com as strings de C,
mas como ela é um objeto (em C ela classe string é um tipo literal), ela pode
receber mensagens. Isso significa que a classe NSString possui métodos, e com
eles é possível concatenar, dividir, buscar por substrings, comparar, transformar,
entre outros.
A forma mais simples de se criar um objeto do tipo NSString é utilizando o
construtor do Objective-C @””, por exemplo NSString *umaString = @”Primeiro
iOS Fundamentos 14
1
seguinte forma:
[umaString length];
1.3 NSLog
iOS Fundamentos 15
description do objeto.
%i: imprime números inteiros.
%f: imprime números fracionários. Nesse caso é possível definir o número de
casas decimais a serem impressas. Por exemplo, se utilizarmos a diretiva alterada
para %.3f, vai fazer com que a parte fracionária do número seja arredondada
para exibir somente três casas decimais.
O resultado seria:
iOS Fundamentos 16
1
iOS Fundamentos 17
1
#import “AppDelegate.h”
@implementation AppDelegate
@synthesize window = window;
_
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(
NSDictionary *)launchOptions
{
iOS Fundamentos 18
1
iOS Fundamentos 19
1
- (void)applicationWillTerminate:(UIApplication *)application
{
NSLog(@”O aplicativo vai fechar.”);
}
@end
iOS Fundamentos 20
1
1.5 UIView
A classe UIView definida no framework UIKit é a base de praticamente todos os
componentes do iOS. Ela define uma área retangular na tela e as informações
necessárias para controlar o conteúdo dentro dela. Uma view pode conter
outras views dentro dela, chamadas subviews, podendo assim criar uma
hierarquia de views mais sofisticada. Uma view pode conter quantas subviews
forem necessárias, mas ela pode ser filha de apenas uma view. A view pai é
conhecida como superview.
Uma view é definida por sua propriedade chamada frame. Um frame é
constituído pelo ponto de origem da view em relação à superview (x e y) e pelo
tamanho do retângulo (largura e altura).
iOS Fundamentos 21
1
Os métodos mais comuns para adicionar uma subview ou remover uma view são:
iOS Fundamentos 22
1
return YES;
}
iOS Fundamentos 23
1
iOS Fundamentos 24
1
1.7) UILabel
A classe UILabel estende a classe UIView para exibir um texto estático na
tela e fornece controle para modificar a aparência do texto. Suas principais
propriedades são:
• font: estilo da fonte do label. Importante notar que o iOS não possui
todas as fontes e se não encontrada a fonte desejada, a fonte padrão é
utilizada.
iOS Fundamentos 25
1
iOS Fundamentos 26
1
iOS Fundamentos 27
1
1.9 UIButton
A classe UIButton implementa um botão, que recebe eventos de toque e envia
mensagens para a classe que responde a elas. A UIButton estende a classe
UIControl, que é a classe base para os componentes que recebem interações.
A classe UIControl não pode ser instanciada diretamente, ela apenas define
uma estrutura comum para suas subclasses, e seu papel fundamental é atribuir
mensagens para ações recebidas por componentes e distribuí-las para os
devidos objetos. Suas principais propriedades são:
iOS Fundamentos 28
1
iOS Fundamentos 29
1
Caso não seja especificado uma imagem ou um texto para o botão nos estados
pressionado ou desabilitado, será usado o valor definido para o estado normal.
iOS Fundamentos 30
1
#import <UIKit/UIKit.h>
-(void)apertouBotao:(id)sender;
@end
iOS Fundamentos 31
1
iOS Fundamentos 32
1
return YES;
}
-(void)apertouBotao:(id)sender {
NSLog(@”Apertou o botão!”);
}
iOS Fundamentos 33
1
iOS Fundamentos 34
iOS: Fundamentos
Capítulo 2
2
2.1 UIViewController
A classe UIViewController fornece o modelo fundamental para controle das
views de um aplicativo para iOS. Toda view controller possui uma view associada
(acessada pela propriedade view) e é responsável por controlar as demais
subviews e responder aos eventos gerados por elas.
Normalmente não é criado instâncias da classe UIViewController, mas sim de
classes que a reimplementam, fazendo com que elas tenham o comportamento
adequado para o aplicativo. Quando estendemos essa classe, alguns métodos
são importantes e merecem uma atenção especial:
iOS Fundamentos 36
2
iOS Fundamentos 37
2
iOS Fundamentos 38
2
#import <UIKit/UIKit.h>
#import “MinhaViewController.h”
@interface AppDelegate : UIResponder <UIApplicationDelegate> {
MinhaViewController *minhaViewController;
}
@property (strong, nonatomic) UIWindow *window;
@end
Depois de importado, vamos alterar o método application:
didFinishLaunchingWithOptions: para inicializar a vairável e atribuí-la como
rottViewController do aplicativo:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(
NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen]
bounds]];
// Override point for customization after application launch.
self.window.backgroundColor = [UIColor greenColor];
[self.window makeKeyAndVisible];
minhaViewController = [[MinhaViewController alloc] init];
[self.window setRootViewController:minhaViewController];
iOS Fundamentos 39
2
return YES;
}
Vamos agora recriar o exemplo do projeto HelloWorld utilizando a classe
MinhaViewController para carregar os componentes. Portanto no arquivo
MinhaViewController.h vamos adicionar o método para o botão:
#import <UIKit/UIKit.h>
@interface MinhaViewController : UIViewController
-(void)apertouBotao:(id)sender;
@end
E no arquivo MinhaViewController.m vamos implementar o método para o
botão e o método loadView:
#pragma mark - MinhaViewController methods
-(void)apertouBotao:(id)sender {
NSLog(@”Apertou o botão na MinhaViewController!”);
}
#pragma mark - View lifecycle
// Implement loadView to create a view hierarchy programmatically, without
using a nib.
- (void)loadView
{
[super loadView];
UIView *primeiraView = [[UIView alloc] initWithFrame:CGRectMake(0, 0,
320, 480)];
iOS Fundamentos 40
2
iOS Fundamentos 41
2
E no console:
ViewControllers[1008:f803] Apertou o botão na MinhaViewController!
iOS Fundamentos 42
2
iOS Fundamentos 43
2
iOS Fundamentos 44
2
indica que esse view controller é o root view controller e possui a mesma
função que a linha [self.window setRootViewController:minhaViewController]; que
utilizamos no AppDelegate.m. Precisamos também alterar o tipo da classe no
campo “Custom Class” de UIViewController para MinhaViewController.
No arquivo MinhaViewController.m, vamos comentar o método loadView, pois
ele deve ser implementado somente quando o carregamento da view não seja
feito por Storyboard ou XIB.
Ao executarmos o aplicativo, teremos o seguinte resultado:
Na grande maioria dos aplicativos para iOS, esse é o ponto inicial para a criação
do aplicativo: um AppDelegate, um ViewController e o Storyboard configurado
para utilizá-lo como root view controller. Para esse tipo de configuração inicial,
o Xcode fornece o template chamado “Single View Application”.
iOS Fundamentos 45
iOS: Fundamentos
Capítulo 3
3
3.1 IBOutlet
O editor de interface do Xcode é uma ferramenta muito completa e possui
todos os componentes básicos para a implementação de um aplicativo, mas
uma interface precisa também de uma ligação com seu controlador. Para que
isso seja possível, utilizamos a constante IBOutlet na definição do componente.
Isso faz com que o editor de interface reconheça aquele componente e
permita fazer a ligação entre o que foi definido no arquivo .h e o Storyboard.
Adicionando essa constante antes do tipo do componente na sua definição no
arquivo .h permite que o editor de interface o reconheça:
3. Exemplo de IBOutlet
Vamos criar um novo projeto do tipo “Single View Application” chamado
“Componentes” utilizando Storyboard e ARC.
iOS Fundamentos 47
3
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController {
IBOutlet UILabel *labelOutlet;
}
@end
iOS Fundamentos 48
3
iOS Fundamentos 49
3
iOS Fundamentos 50
3
iOS Fundamentos 51
3
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
labelOutlet.backgroundColor = [UIColor yellowColor];
}
Como o componente está definido na Scene do Storyboard, não precisamos
inicializá-lo, pois ele ocorre automaticamente ao carregar a view e suas
subviews.
Ao executarmos o aplicativo, obtemos o seguinte resultado:
Figura 3.6: Execução do aplicativo
3.3 IBAction
A constante IBAction funciona de uma forma semelhante a IBOutlet, mas para
mensagens enviadas para os componentes. Utilizamos essa constante como
retorno do método que queremos utilizar, que possui o mesmo valor de void, e
o editor de interface passa a reconhecer esse método na aba de conexões do
view controller.
iOS Fundamentos 52
3
#import <UIKit/UIKit.h>
-(IBAction)apertouBotao:(id)sender;
@end
iOS Fundamentos 53
3
iOS Fundamentos 54
3
iOS Fundamentos 55
3
3.5 UISlider
Um objeto do tipo UISlider é um componente utilizado para selecionar valores
contínuos de um determinado intervalo. Diferente do botão, o slider é baseado
valor atual, e por isso os métodos são chamados com evento do tipo “Value
Changed”. Suas principais propriedades são:
#import <UIKit/UIKit.h>
iOS Fundamentos 56
3
-(IBAction)apertouBotao:(id)sender;
-(IBAction)alterouSlider:(id)sender;
@end
iOS Fundamentos 57
3
-(IBAction)alterouSlider:(id)sender {
UISlider *senderSlider = (UISlider *) sender;
labelOutlet.text = [NSString stringWithFormat:@”Novo valor do slider: %.2f”,
senderSlider.value];
}
3.7 UISwitch
Um objeto do tipo UISwitch é utilizado para selecionar dois tipos valores: ligado
ou desligado. É baseado também nos valores, e portanto uma ação deve ser
iOS Fundamentos 58
3
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController {
IBOutlet UILabel *labelOutlet;
IBOutlet UIButton *botao;
IBOutlet UISlider *slider;
}
-(IBAction)apertouBotao:(id)sender;
-(IBAction)alterouSlider:(id)sender;
-(IBAction)alterouSwitch:(id)sender;
@end
iOS Fundamentos 59
3
-(IBAction)alterouSwitch:(id)sender {
UISwitch *senderSwitch = (UISwitch *)sender;
botao.enabled = senderSwitch.on;
slider.enabled = senderSwitch.on;
if (senderSwitch.on) {
labelOutlet.text = @”Componentes habilitados”;
} else {
labelOutlet.text = @”Componentes desabilitados”;
iOS Fundamentos 60
3
}
}
iOS Fundamentos 61
iOS: Fundamentos
Capítulo 4
4
iOS Fundamentos 63
4
iOS Fundamentos 64
4
iOS Fundamentos 65
4
iOS Fundamentos 66
4
4.3 UISegmentedControl
Um objeto do tipo UISegmentedControl é um componente horizontal com
segmentos que funcionam como botões, portanto somente um segmento pode
estar selecionado. Suas principais propriedades são:
#import <UIKit/UIKit.h>
}
-(IBAction)mudarImagem:(id)sender;
@end
iOS Fundamentos 68
4
Por fim, vamos implementar o método mudarImagem: para quando for alterado
o segmento selecionado, trocar para a imagem correspondente. Portanto o
método ficará assim no arquivo ViewController.m:
iOS Fundamentos 69
4
break;
case 2:
nomeImagem = @”Parrot.tif”;
break;
default:
break;
}
UIImage *novaImagem = [UIImage imageNamed:nomeImagem];
imageView.image = novaImagem;
}
iOS Fundamentos 70
4
4.5 Delegate
O Objective-C possui um mecanismo no qual um objeto guarda uma referência
para outro objeto que responde mensagens definidas em um protocolo. Esse
mecanismo é chamado “Delegation” e o objeto que recebe as mensagens é
chamado “delegate”. De uma forma geral, um objeto delega uma tarefa para
outro objeto, o delegate. E como isso pode ser útil? Com o delegate, é possível
customizar o comportamento dos componentes sem precisar criar uma nova
classe customizada que estende o componente. Portanto o objeto que envia a
mensagem é, geralmente, um componente já existente e o delegate é o objeto
do view controller customizado e que implementa o protocolo.
Os protocolos definem as possíveis mensagens que o delegate pode receber
do outro objeto. Para a classe que vai implementar os métodos, eles são
classificados de duas maneiras: ou sua implementação é obrigatória (@required)
ou é opcional (@optional).
Para uma classe implementar um protocolo, é necessário adicionar o protocolo
na definição da interface da classe, no arquivo .h. Por exemplo:
iOS Fundamentos 71
4
iOS Fundamentos 72
4
#import <UIKit/UIKit.h>
iOS Fundamentos 73
4
-(IBAction)mudarImagem:(id)sender;
@end
iOS Fundamentos 74
4
iOS Fundamentos 75
4
iOS Fundamentos 76
iOS: Fundamentos
Capítulo 5
5
5.1 DataSource
Assim como nos delegates, algumas classes enviam mensagens para seus
datasources. O datasource é muito semelhantes ao delegate, ele permite
que a classe seja customizada sem precisar estendê-la. Entretanto, a função
de um datasource (no português fonte de dados) é fornecer as informações
necessárias e os dados para popular seu objeto. Assim como o delegate, os
métodos do datasource podem ser opcionais ou obrigatórios.
5.2 UIPickerView
A classe UIPickerView implementa um componente giratório, como uma
máquina de caça-níqueis, para selecionar um valor dentro de uma lista de
possibilidades alinhando o valor desejado no centro do componente. Um picker
view possui colunas e cada coluna possui valores diferentes para suas linhas e
ambas são acessadas por índices.
Quando utilizamos um picker view, precisamos implementar os
protocolos UIPickerViewDelegate (para construir o componente) e o
UIPickerViewDataSource (para prover o número de colunas e linhas do
componente).
As principais propriedades do UIPickerView são:
iOS Fundamentos 78
5
iOS Fundamentos 79
5
5.3 NSArray
A classe NSArray guarda uma lista ordenada de objetos, chamada de array.
Um objeto dessa classe pode conter qualquer objeto que derive da classe
NSObject, seja direta ou indiretamente e não precisa ser de um tipo específico,
pode conter qualquer objeto, desde que seja tratado corretamente.
Um objeto da classe NSArray é imutável e deve ser construído no momento da
sua inicialização. Seus principais métodos são:
iOS Fundamentos 80
5
#import <UIKit/UIKit.h>
NSArray *info;
}
@end
Definimos também uma variável de classe chamada info, que vai guardar o nome
das imagens.
Vamos adicionar agora um UIImageView na Scene do Storyboard e um
UIPickerView. Temos que fazer a ligação do IBOutlet à imagem e do delegate e
datasource ao view controller. A Scene vai ficar assim:
iOS Fundamentos 81
5
iOS Fundamentos 82
5
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 1;
}
iOS Fundamentos 83
5
iOS Fundamentos 84
iOS: Fundamentos
Capítulo 6
6
6.1 UIScrollView
A classe UIScrollView fornece o suporte para exibir um conteúdo que é maior
que a tela, suportando a navegação do usuário pelo conteúdo do componente
e também o zoom fazendo gestos de pinça. O conteúdo do scroll view pode
ter qualquer tamanho, mas somente será exibido a parte que está dentro
do frame. Um scroll view pode ter um delegate, que deve obrigatoriamente
implementar o protocolo UIScrollViewDelegate.
As principais propriedades do UIScrollView são:
iOS Fundamentos 86
6
6.2 UIPageControl
A classe UIPageControl é um componente controlador de páginas, que
geralmente é exibido junto de um scroll view. Ele é um conjunto de bolinhas
centralizadas no componente que correspondem aos elementos do scroll e
uma delas para o elemento que está sendo exibido. Suas principais propriedades
são:
6.3 Exemplo
Vamos criar um novo projeto do tipo “Single View Application”chamado
“Slideshow”, utilizando Storyboard e ARC, e vamos adicionar algumas imagens
ao projeto. Vamos alterar o arquivo ViewController.h para ele implementar o
protocolo UIScrollViewDelegate e adicionar dois IBOutlets (um para o scroll
view e outro para o page control) e um IBAction, que será chamado quando
tocarmos em cima do page control:
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController <UIScrollViewDelegate> {
IBOutlet UIScrollView *scroll;
IBOutlet UIPageControl *page;
}
iOS Fundamentos 87
6
-(IBAction)mudarPagina:(id)sender;
@end
iOS Fundamentos 88
6
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
iOS Fundamentos 89
6
iOS Fundamentos 90
6
Em seguida precisamos alterar a página atual exibida pelo page control quando
navegamos pelo scroll view. Para isso temos duas opções de implementação e
varia de caso para caso para saber qual é a mais interessante de se utilizar no
aplicativo, dependendo de sua funcionalidade. O método scrollViewDidScroll:
é chamado toda vez que é alterado a posição dentro do scroll, enquanto o
método scrollViewDidEndDecelerating: é chamado somente quando o scroll
estiver parando. É recomendado utilizar o segundo método pois ele é suficiente
para a maioria dos casos e, principalmente, quando tarefas muito pesadas
precisam ser executadas, ele obtém melhor performance que o primeiro.
Portanto no exemplo vamos implementar o segundo método para alterar a
página atual do page control:
iOS Fundamentos 91
6
-(IBAction)mudarPagina:(id)sender {
[scroll scrollRectToVisible:CGRectMake(scroll.frame.size.width*page.
currentPage, 0, scroll.frame.size.width, scroll.frame.size.height) animated:YES];
}
iOS Fundamentos 92
6
#import <UIKit/UIKit.h>
@end
iOS Fundamentos 94
6
iOS Fundamentos 95
6
iOS Fundamentos 96
iOS: Fundamentos
Capítulo 7
7
7.2 Exemplo
Vamos criar um novo projeto do tipo “Single View Application” chamado
“ModalViews”, utilizando Storyboard e ARC. Em seguida vamos criar um
novo view controller chamado “NovoViewController”, subclasse de
UIViewController e sem XIB. Depois de criado, vamos adicionar um novo
UIViewController ao Storyboard e alterar o campo Custom Class da aba de
Identidade para a classe NovoViewController.
iOS Fundamentos 98
7
iOS Fundamentos 99
7
#import <UIKit/UIKit.h>
-(IBAction)voltar:(id)sender;
@end
Também é possível alterar o tipo de transição utilizando Segues, para isso basta
alterar a propriedade “Transition” nos seus atributos:
ViewController.h:
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
-(IBAction)mudaViewController:(id)sender;
@end
#import “NovoViewController.h”
-(void)mudaViewController:(id)sender {
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@”Main
Storyboard” bundle:nil];
o atributo weak faz com que a propriedade guarde apenas uma referência para
o objeto. Importante notar que no segundo caso, o objeto pode ser removido
da memória por alguma outra classe e a propriedade pode apontar para
um bloco de memória errado. Ambos os atributos são válidos apenas para
propriedades do tipo NSObject ou suas subclasses.
@synthesize nomeDaPropriedade;
#import <UIKit/UIKit.h>
@interface NovoViewController : UIViewController {
IBOutlet UILabel *label;
}
@property (nonatomic, strong) NSString *textLabel;
-(IBAction)voltar:(id)sender;
@end
Em seguida vamos adicionar um label na Scene do NovoViewController no
Storyboard e ligar o IBOutlet:
- (void)viewDidLoad
{
[super viewDidLoad];
if (textLabel && ![textLabel isEqualToString:@””]) {
label.text = textLabel;
}
}
-(void)mudaViewController:(id)sender {
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@”Main
Storyboard” bundle:nil];
NovoViewController *novoViewController = [mainStoryboard instantiateVie
wControllerWithIdentifier:@”NovoViewController”];
novoViewController.textLabel = @”Propriedade alterada no IBAction!”;
novoViewController.modalTransitionStyle =
UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:novoViewController animated:YES];
}
Para identificarmos a classe destino que vai ser chamada pelo Segue, utilizamos
o método chamado isKindOfClass:, que recebe como parâmetro o objeto do
tipo Class e retorna verdadeiro quando o objeto for da mesma classe ou uma
subclasse dele. Como esse método é chamado para todos os Segues dessa
classe, é importante fazer esse tipo de verificação antes de fazer o cast e
acessar a propriedade da classe, caso contrário poderá ocorrer um erro de
execução e o aplicativo pode travar.
Ao executarmos o aplicativo, teremos o seguinte resultado:
Capítulo 8
8
8.1 UINavigationController
A classe UINavigationController estende a classe UIViewController para
implementar um view controller especial para controlar uma navegação em que
diferentes subníveis são mostrados a medida que itens são selecionados. Cada
tela de cada nível da navegação é controlada por seu próprio view controller,
enquanto a navegação entre as telas é controlada pelo navigation controller.
Essa classe não precisa ser estendida e sua implementação fornece uma
interface pronta para todas as situações.
Um navigation controller controla as telas apresentadas em uma pilha
de navegação, ou seja, o item na parte de baixo da pilha é o primeiro view
controller exibido, conhecido como root view controller, enquanto o item mais
acima da pilha é o view controller que está sendo exibido no momento.
Para fazer o controle da navegação entre os view controllers exibidos, o
navigation controller possui dois métodos:
#import <UIKit/UIKit.h>
@end
#import <UIKit/UIKit.h>
-(IBAction)mudarViaCodigo:(id)sender;
@end
#import <UIKit/UIKit.h>
return cell;
}
Precisamos implementar esse método para que ele retorne o objeto do tipo
UITableViewCell referente ao item da tabela com o indexPath passado como
parâmetro. Como uma tabela pode possuir muitos itens e seções, e para não
utilizar muita memória e melhorar sua performance, a classe UITableView é
implementada da seguinte forma: somente é carregado na memória os itens
que estão sendo exibidos na tela e a medida que é feita a navegação entre os
itens da tabela, os itens que somem são reutilizados para criar os próximos itens
que estão aparecendo. E o método dequeueReusableCellWithIdentifier: faz
exatamente isso utilizando o identificador para a célula, e retorna o objeto que
pode ser reutilizado ou então nil caso ainda não existam células que possam
ser reutilizadas. Caso a tabela não consiga reutilizar a célula, então ela é criada
através do método initWithStyle: reuseIdentifier:, que recebe um estilo de
célula e o identificador para reutilização. Depois de criada a célula, alteramos
seu texto para exibir a seção e a linha da tabela e então retornamos o objeto
referente à célula.
Ao executarmos teremos os seguinte resultado, primeiro com o estilo Plain e
depois com o estilo Grouped da tabela:
8.6 UITableViewController
Ao analisarmos a classe PrimeiraViewController, ela é do tipo
UIViewController e implementa os protocolos UITablewViewDelegate e o
UITableViewDataSource, além de possuir uma tabela na sua interface. Isso é
exatamente uma classe do tipo UITableViewController. Essa classe fornece
todos os componentes necessários para implementarmos uma tabela, e
assim como não utilizamos diretamente a classe UIViewController, o mesmo
acontece com a UITableViewController.
Uma das diferenças entre a implementação da classe PrimeiraViewController
Capítulo 9
9
9.1 NSDictionary
Um objeto do tipo NSDictionary (ou dicionário) contém associações de
pares chave-valor. Cada par desses possui um objeto que representa a chave
(geralmente do tipo NSString) e o outro objeto que é o valor recuperado por
essa chave. Toda chave do dicionário deve ser única, ou seja, não pode existir
dois pares que possuam a mesma chave para objetos diferentes.
Os principais métodos da classe NSDictionary são:
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
Para cada animal criamos um dicionário com suas informações e depois criamos
um array com esses dicionários.
Em seguida vamos implementar os método do datasource da tabela:
#import <UIKit/UIKit.h>
@end
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.title = [self.detailItem objectForKey:@”nome”];
especie.text = [self.detailItem objectForKey:@”especie”];
imagem.image = [UIImage imageNamed:[self.detailItem
objectForKey:@”imagem”]];
}
Ao rodarmos o aplicativo, teremos o seguinte resultado:
<array>: guarda um array de objetos e seu conteúdo pode conter qualquer tipo
de tag.
<dict>: guarda um dicionário e seu conteúdo deve conter a tag <key>, cujo
conteúdo será a chave do par, e o objeto seguinte será o valor que essa chave
representa.
<plist version=”1.0”>
<array>
<dict>
<key>nome</key>
<string>Águia</string>
<key>especie</key>
<string>Ave</string>
<key>imagem</key>
<string>Eagle.tif</string>
</dict>
<dict>
<key>nome</key>
<string>Coruja</string>
<key>especie</key>
<string>Ave</string>
<key>imagem</key>
<string>Owl.tif</string>
</dict>
<dict>
<key>nome</key>
<string>Arara</string>
<key>especie</key>
<string>Ave</string>
<key>imagem</key>
<string>Parrot.tif</string>
</dict>
<dict>
<key>nome</key>
<string>Pinguim</string>
<key>especie</key>
<string>Ave</string>
<key>imagem</key>
<string>Penguin.tif</string>
</dict>
<dict>
<key>nome</key>
<string>Zebra</string>
<key>especie</key>
<string>Mamífero</string>
<key>imagem</key>
<string>Zebra.tif</string>
</dict>
</array>
</plist>
Reparem que a primeira tag após a tag <plist> é <array> e não um <dict> como
fica no arquivo recém criado. Visualmente a plist ficará assim:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
classes são extensões das classes imutáveis com a adição de métodos para o
controle de seus conteúdos.
A classe NSMutableString possui praticamente os mesmos métodos da
classe NSString, com a diferença que a segunda cria um novo objeto como
retorno do método, enquanto a primeira vai alterar o objeto que está
recebendo a mensagem. Por exemplo, na classe NSString existe o método
stringByAppendingFormat: que retorna uma nova string resultado da
concatenação das duas strings, enquanto a classe NSMutableString possui
o método appendFormat: que altera o objeto que recebe a mensagem,
concatenando a string passada como parâmetro.
A classe NSMutableArray possui os seguintes métodos:
tableView: targetIndexPathForMoveFromRowAtIndexPath:
toProposedIndexPath: retorna o indexPath final do item a ser movimentado,
recebendo como parâmetro o indexPath inicial e o final. Esse método não
é necessário, pois sua implementação básica sempre retorna o indexPath
final, mas é importante nos casos que não queremos que um item seja
movimentado para determinada posição, retornando então o indexPath inicial.
#import <UIKit/UIKit.h>
@interface MasterViewController : UITableViewController {
NSMutableArray *tableInfo;
}
@end
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.navigationItem.rightBarButtonItem = self.editButtonItem;
NSString *path = [[NSBundle mainBundle] pathForResource:@”animais”
ofType:@”plist”];
tableInfo = [NSMutableArray arrayWithContentsOfFile:path];
}
if (editingStyle == UITableViewCellEditingStyleDelete) {
[tableInfo removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
} else if (editingStyle == UITableViewCellEditingStyleInsert) {
// código para adicionar item
}
}
Path *)indexPath
{
return YES;
}
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath
*)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
[tableInfo exchangeObjectAtIndex:fromIndexPath.row
withObjectAtIndex:toIndexPath.row];
}
No primeiro método apenas informamos que todos os itens podem ser movidos,
mas como no método tableView: canEditRowAtIndexPath: informamos que o
item com índice 1 não poderia ser editado, isso vale para esse caso também. No
método seguinte fazemos apenas as alterações necessárias no array, trocando a
posição de seus itens.
Ao executarmos o aplicativo, teremos o seguinte resultado:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.navigationItem.rightBarButtonItem = self.editButtonItem;
Capítulo 10
10
10.1 UITabBarController
A classe UITabBarController é uma extensão da classe UIViewController,
customizada para exibir uma navegação por abas de diferentes view controllers
e, assim como a UINavigationController, essa classe não precisa ser estendida.
Ela possui uma barra que contém as abas, e cada uma das abas é associada
a uma view controller, Essa barra de abas, ou tabbar, deve ser levada em
consideração quando é feita a interface do view controller.
Quando o usuário seleciona uma aba, o tabbar controller carrega e exibe a
view do view controller correspondente. Se a view já tinha sido carregada
ela é exibida na mesma posição em que ela estava anteriormente (imagine um
navigation controller com três view controllers na sua pilha, quando voltar para
sua aba correspondente, ele exibirá a mesma view controller de antes).
Cada aba da tabbar, definida pela classe UITabBarItem, possui um título e uma
imagem que será exibida junto do título e o próprio tabbar controller faz a
coloração azul quando uma aba é selecionada. Para isso, essa imagem deve
ser definida de acordo com sua propriedade alpha, em que ela é delimitada
pelos pixels que não são transparentes, ou seja, não importa a cor da imagem,
ela será sempre cinza na tabbar (seu tamanho deve ser de 30x30 pixels). Por
exemplo, a imagem abaixo mostra uma imagem original ao lado da imagem da
aba selecionada a aba não selecionada dessa imagem:
Por último vamos adicionar um novo view controller e fazer um botão para
navegarmos dentro do navigation controller:
10.5 Exemplo
Vamos criar um exemplo do tipo “Single View Application” chamado “Icones”
utilizando Storyboard e ARC. Vamos adicionar imagens para o ícone do
aplicativo e para o splash screen. Para isso basta arrastarmos as imagens
desejadas para o espaço correto nas preferencias do target do projeto:
Vamos agora adicionar a mesma imagem três vezes ao projeto de acordo com a
tabela abaixo:
Nome da Imagem Tamanho (pixels)
Eagle.png 200x200
EagleRetina.png 200x200
EagleRetina@2x.png 400x400
Notem que a imagem Eagle.png não possui uma versão para tela de retina,
enquanto a EagleRetina.png possui sua correspondente. Agora no arquivo
de Storboard, na Scene referente ao ViewController, vamos adicionar duas
imagens, e associar a uma dela a imagem Eagle.png e a outra a imagem
EagleRetina.png. Vamos adicionar também um label para identificar as imagens.
Ao rodarmos o aplicativo primeiro em um iPhone com tela normal e depois em
um iPhone com tela de retina, teremos o seguinte resultado:
Dessa forma não dá para notar muito a diferença, portanto vamos aproximar
a imagem na execução do iPhone com tela de retina para percebermos a
diferença:
Bundle display name: nome que aparece abaixo do ícone na tela do aparelho
(valor default é o nome do projeto, que é guardado na variável PRODUCT_
NAME e é utilizado ${PRODUCT_ NAME} para recuperar seu conteúdo).
Icon files (iOS 5.0): ícone dos aplicativos para aparelhos rodando iOS 5.0 (para
versões anteriores do iOS, utilizar o campo “Icon files”). O item “Icon already
includes gloss effects” informa se o ícone utilizado já possui efeito de brilho ou não.
iOS Fundamentos 178
10
Main storyboard file base name: nome do storyboard onde está definido o
início do aplicativo.
Status bar style: tipo da barra de status do dispositivo (cinza, preta opaca o
preta translúcida).