Desenvolvimento para iOS com Xcode

Este artigo aborda a construção de um aplicativo simples para iOS, visando apresentar ao leitor o conhecimento necessário para iniciar no desenvolvimento de aplicativos para esta plataforma. Pouco-a-pouco o leitor irá se familiarizar com o uso do Xcode (IDE de desenvolvimento da Apple), a utilização de storyboards na construção de aplicativos, o padrão de projetos MVC (Model-View-Controller) e alguns dos componentes de interface de usuário mais comuns.

Espera-se que com esta leitura, um desenvolvedor iniciante tenha uma visão geral dos itens necessários para o desenvolvimento de aplicativos iOS e que a partir de então seja capaz de construir seus próprios aplicativos de maneira autônoma.

O desenvolvimento de aplicativos para iOS (iPod, iPhone e iPad) é baseado em uma linguagem de programação chamada Objective-C, também conhecida por ObjC. Ela é uma linguagem de programação orientada a objetos que adiciona o estilo de troca de mensagens de Smalltalk à linguagem de programação C. Foi desenvolvida nos anos 80 pela StepStone e adotada e popularizada pela NeXT para seu sistema operacional NeXTSTEP, de onde o OS X e iOS nasceram.

O ObjC fornece a sintaxe para os comandos que utilizamos em nosso aplicativo, no entanto ele não oferece suporte a interface de usuários, recursos em rede ou à leitura de arquivos. Este suporte vem da biblioteca Cocoa Touch, desenvolvida pela Apple e formada por diversos frameworks (coleções de classes agrupadas).

Os frameworks mais utilizados, e que dão suporte básico à construção de aplicativos iOS, são o Foundation Kit, que fornece as estruturadas de dados, recursos de rede, recursos de entrada e saída e tratamento de strings, entre outros; e o UIKit, projetado para auxiliar no desenvolvimento de GUIs (Graphical User Interfaces).

Para facilitar o desenvolvimento de aplicativos iOS, a Apple disponibiliza de maneira gratuita para os desenvolvedores o Xcode, uma IDE (Integrated Development Environment) bastante poderosa e fácil de utilizar.

O Xcode possui diversas ferramentas muito úteis, entre as mais importantes podemos citar o compilador da Apple LLVM, que além de compilar o código, fornece uma ferramenta inteligente de para completar o código; o Interface Builder (IB), no qual trabalhamos na parte visual do aplicativo, construindo nossas telas; uma ferramenta para debug; o Organizer, que auxilia no gerenciamento de projetos e dispositivos cadastrados para testes, além de apresentar a documentação auxiliar; o Instruments; uma ferramenta para análise de desempenho do código; e por fim o iOS Simulator, um simulador para iPhone e iPad no qual podemos verificar nossos aplicativos.

Cada aplicativo desenvolvido pode e deve ser testado não só no simulador, mas também em dispositivos reais. Além do mais, apesar do simulador possuir funcionalidades importantes como toque, gestos e GPS, algumas funcionalidades como as do acelerômetro ou bússola, não foram disponibilizadas, desta forma faz-se extremamente necessário os testes em dispositivos reais.

Para que se possa testar seus aplicativos em dispositivos reais é necessário que o desenvolvedor tenha uma conta junto a Apple, desta forma o mesmo pode cadastrar seus dispositivos, realizar os testes e submeter seus aplicativos para AppStore (loja virtual da Apple). O cadastro de uma conta de desenvolvedor é realizado direto no site de desenvolvimento da Apple (Developer Apple), e custa 99 dólares por ano.

Por fim, é importante entender que os aplicativos para iOS seguem o padrão MVC (Model-View-Controller). Este padrão separa o modelo, um conjunto de classes que manipula dados, das views, interfaces de usuários ou telas, e permite que um controlador (controller) gerencie o fluxo de informações entre o modelo e as telas.

Isto facilita a construção de projetos universais, que são projetos tanto para iPhone/iPod, quanto para iPad. Desta forma, o desenvolvedor pode reaproveitar todo o código do modelo e do controller para ambos dispositivos e só necessita realizar trabalho extra nas views, uma para iPad e outra para iPhone.

É muito comum, especialmente em aplicativos mais simples, não implementarmos classes para o modelo. Estes aplicativos seguem uma lógica que apenas necessita de uma tela e um controlador desta, já que não há dados a serem armazenados.

A partir de agora, após apresentados os conceitos inicias, podemos partir para a prática. O restante deste artigo apresenta o desenvolvimento passo-a-passo de um aplicativo simples que visa introduzir ao leitor o conhecimento necessário para iniciar no construção de aplicativos para esta iOS.

Pouco-a-pouco o leitor irá se familiarizar com o uso do Xcode, a utilização de storyboards na construção de aplicativos e alguns dos componentes de interface de usuário mais comuns.

O projeto – Assistente de Conta

Iremos agora desenvolver um aplicativo iOS, chamado Assistente de Conta, que tem por objetivo auxiliar seu usuário a acertar a conta em um restaurante ou bar. O aplicativo recebe como entrada o valor da conta a ser paga em um restaurante ou bar e mostra o valor da gorjeta a ser acrescentada a conta, permitindo a customização da gorjeta a partir de um componente de UI (User Interface) chamado spinner. Além disto, é possível também dividir a conta por uma quantidade de pessoas, informando o total por pessoa.

Apesar de simples, o Assistente de Conta, utiliza conceitos importantes para a formação do leitor como desenvolvedor iOS. Esta experiência prática irá permitir que o leitor possa desenvolvedor novos aplicativos de maneira autônoma. Para a construção deste aplicativo, estão sendo usados o Xcode versão 5.0 e o sdk para iOS 7. Como o Assistente de Conta é simples, ele pode ser implementado sem problemas nas versões anteriores do Xcode.

Para começar inicie o Xcode e escolha a criação de um novo projeto iOS com o template Single View Application, como mostra a Figura 1. Existem diferentes templates que podem ser utilizados na criação de projetos pelo Xcode, eles visam acelerar o desenvolvimento de um aplicativo baseado em certo estilo. O Single View Application é um template que nos fornece uma única view (tela) já vinculada a um controlador, conforme veremos mais adiante.

Criação de um projeto Single View Application
Figura 1.Criação de um projeto Single View Application.

Após a seleção do template partimos para a identificação do projeto. Nomeie o projeto como assistenteDeConta, e coloque como o nome da organização a palavra DevMedia. A organização é nome da empresa que está submetendo o aplicativo para a Apple, em caso de desenvolvedor individual pode ser colocado seu nome. O campo identificador da empresa identifica o domínio da insittuição para a Apple, normalmente em modo reverso. Insira neste campo o valor br.com.devmedia. Finalmente, o identificador único do aplicativo (Bundle Identifier) é criado, ele une o domínio utilizado ao nome do aplicativo e identifica de forma única este aplicativo para a Apple.

O campo de prefixo de classe é opcional, se usado descreve um prefixo que será adicionado a todas as classes criadas no projeto, vamos inserir o valor adc (assistente de conta). Por fim, selecione iPhone como o dispositivo que será o alvo deste projeto. A Figura 2 ilustra o preenchimento dos dados desta etapa.

Preenchimento de dados
de identificação de um projeto
Figura 2.Preenchimento de dados de identificação de um projeto.

Com o projeto criado temos uma estrutura de arquivos e pastas a serem exploradas. Note que encontramos nesta estrutura os arquivos adcAppDelegate, adcViewController e Main.storyboard. O primeiro serve como um local central para implementarmos os métodos que irão gerenciar o comportamento do aplicativo, por exemplo, o que mostrar quando o aplicativo for inicializado, o que fazer quando ele for colocado em background pelo usuário, entre outros.

O adcViewController é a implementação da classe controladora de nossa única tela, ele descreve as ações a serem realizadas a partir do momento da captura da entrada de dados, até a impressão na tela dos resultados do aplicativo. Ambos arquivos possuem uma versão .h e outra .m. O arquivo .h é conhecido como arquivo cabeçalho (header).

Neste podemos inserir as definições de atributos e propriedades da classe, bem como métodos, e ações a serem implementadas no arquivo .m.

A Figura 3 mostra a estrutura do projeto criado. A pasta Supporting Files é utilizada para inserirmos arquivos de imagens, áudio e outros que dão suporte ao aplicativo. A pasta assistenteDeContasTests é utilizada para implementarmos testes unitários a serem executados no aplicativo, em tempo de desenvolvimento; a Frameworks armazena o conjunto de frameworks a serem utilizados e a Products contém os binários do aplicativo a serem submetidos para a AppStore.

Estrutura de um
projeto no Xcode
Figura 3.Estrutura de um projeto no Xcode.

O arquivo de AppDelegate já vem configurado por padrão para mostrar a nossa Main storyboard, isto acontece no momento da criação do projeto pelo Xcode. Abra o arquivo Main.storyboard, clicando apenas uma única vez neste, e note que há uma view criada com uma seta apontando para a mesma, conforme ilustrado pela Figura 4. Esta seta indica que o AppDelegate vai abrir esta view assim que o aplicativo for executado pelo usuário, ou seja, a seta indica que esta tela é a primeira a ser carregada pelo aplicativo.

Pode-se facilmente incluir novas telas e criar um fluxo de telas com o storyboard rapidamente, não é o nosso caso, já que nosso aplicativo terá apenas uma view.

Ainda com o storyboard aberto, vamos agora explorar as opções de interface que o mesmo nos oferece. Note os ícones do canto direito superior da tela, a Figura 4 ilustra estes ícones, eles nos permitem modificar diversos parâmetros de configuração das views no storyboard. O primeiro ícone é o File Inspector, ele traz diversas informações sobre o arquivo do storyboard que está sendo explorado, como caminho absoluto do mesmo e a versão do Xcode e SDK sendo utilizadas. O segundo ícone traz informações de ajuda sobre o componente selecionado.

O terceiro ícone é bastante importante, ele é o Identity Inspector, e vincula uma view a seu controlador. Para verificar qual o controlador da nossa view, clique no retângulo cinza abaixo da view, ele irá selecionar a view, e uma borda azul irá aparecer ao redor da mesma, conforme ilustrado na Figura 5.

Com a view selecionada, clique no Identity Inspector e verifique que o controlador desta view já está selecionado para a classe adcViewController. Esta classe, bem como seu vínculo com a view, foram criados automaticamente quando selecionamos o template do projeto para Single View Application. O quarto ícone é o Attributes Inspector, ele também é muito importante, pois mostra e permite alterar os atributos do componente de interface de usuário selecionado. Finalmente, o quinto ícone mostra as medidas de cada componente e o último ícone mostra as conexões dos componentes gráficos da view com o seu controlador.

Ícones de opções/informações do storyboard
Figura 4.Ícones de opções/informações do storyboard.
View selecionada
Figura 5.View selecionada.

Vamos começar o desenvolvimento pela nossa view. Selecione a view clicando internamente à mesma e clique no ícone Attributes Inspector. Procure pela propriedade background para que possamos mudar o fundo da view. Selecione a cor Light Gray Color. Verifique se a cor de fundo da view foi modificada. Na parte inferior direita do storyboard, temos a biblioteca de componentes (object library), conforme ilustra a Figura 6.

Object Library
Figura 6. Object Library.

Selecione, na biblioteca de objetos, e arraste para dentro da view um componente chamada Navigation Bar. Posicione-o na parte superior da view, logo abaixo do ícone da bateria, conforme a Figura 7. Edite o título para “Assistente de Conta”. Vamos aproveitar para executar nosso aplicativo e ver o simulador em ação. Clique no ícone play (executar) no canto superior esquerdo da tela ou pressione ⌘+r para executar nosso aplicativo. Veja que o simulador é aberto e nosso aplicativo iniciado.

View com o Navigation Bar posicionado
Figura 7. View com o Navigation Bar posicionado.

Insira agora um Label e um Text Field logo abaixo no Navigation Bar, conforme ilustra a Figura 8. Use os marcadores, linhas pontilhadas azuis, que irão aparecer para auxiliá-lo no posicionamento dos componentes gráficos. Mude o texto do Label, clicando no mesmo, para mostrar a palavra “Conta: “.

Adição do Label e Text Field para inserção de
dados
Figura 8. Adição do Label e Text Field para inserção de dados.

Continue o aplicativo inserindo, logo abaixo da seção de entrada de dados, mais um Label com a palavra “Gorjeta:”, um Slider e dois outros Labels, um com o valor 10 e outro logo em seguida com o símbolo %. Adicione mais dois Labels e dois Text Fields, conforme ilustra a Figura 9.

Seção da gorjeta
Figura 9. Seção da gorjeta.

Clique no Slider e configure as propriedades de valores conforme a Figura 10. Valor mínimo para 0, valor máximo para 100% e valor atual para 10%.

Configuração do Slider
Figura 10.Configuração do Slider.

Vamos disponibilizar também uma área do aplicativo para que o usuário possa saber quanto cada pagante deverá contribuir na conta. Para tal, abaixo da área da gorjeta insira três Labels, dois Text Fields e um Stepper, conforme ilustra a Figura 11. Selecione todos os Text Fields, exceto o referente ao valor de entrada da conta, mantenha a tecla ⌘ para selecionar mais de um componente.

Com os campos selecionados, clique no ícone do Attribute Inspector, e mude a propriedade Border Style dos mesmos para 3D e o alinhamento de texto, propriedade Alignment, para direita. Ainda no Inspector, procure pela seção Control e a propriedade Enabled. Desmarque esta propriedade. Por fim, insira o valor 1 no Text Field referente ao número de pagantes.

View final do Assistente de Conta
Figura 11. View final do Assistente de Conta.

Clique no Stepper e configure suas propriedades de valor mínimo para 1, máximo para 100. Configure também o valor de atual e passo para 1, conforme apresentado na Figura 12.

Configuração do Stepper
Figura 12. Configuração do Stepper.

Com a view finalizada, podemos partir para a implementação do controller. Para tal, vamos iniciar mapeando os componentes de nossa view para objetos em nosso código. Mantenha a Main.storyboard aberta e clique no ícone Assistant Editor, como o mostrado ao lado Assistant Editor. Verifique se o arquivo aberto ao lado da storyboard é o adcViewController.h, conforme pode ser visto na Listagem 1. É neste arquivo que temos que declarar os atributos e propriedades de nossa classe controladora, além dos métodos e ações que a mesma deve implementar.

Listagem 1: adcViewController.h

  #import <UIKit/UIKit.h>
  @interface adcViewController : UIViewController
  @end

Clique com o botão direito do mouse no campo de texto de entrada da conta e puxe um conector para o arquivo adcViewController.h, tenha certeza de soltar o conector antes da diretiva @end deste arquivo, conforme ilustra a Figura 13. Estas conexões são conhecidas por IBOutles (IB – Interface Builder).

Criando uma conexão
entre componente de UI e objeto
Figura 13. Criando uma conexão entre componente de UI e objeto.

Ao largar o conector internamente ao arquivo .h, uma nova tela para criar o objeto, que irá manipular o componente gráfico, é mostrada, conforme a ilustra Figura 14. Nesta podemos definir que tipo de conexão que estamos fazendo, se um outlet ou uma ação (nosso caso é outlet), nomear o objeto e definir o tipo de ligação e gerenciamento de memória que este objeto terá com nosso aplicativo (nosso caso é weak).

Criação do IBOutlet
Figura 14. Criação do IBOutlet.

Ao finalizar uma conexão temos criado um novo objeto em nosso código, neste caso acabamos de criar o objeto inputTxt que irá manipular o campo de texto referente ao valor da conta digitado. Note que no arquivo adcViewController.h há uma nova linha com a diretiva @property para a criação e vinculação do objeto ao componente, conforme mostra a Listagem 2 (linha 13).

Listagem 2. Criação do outlet inputTxt.

  9 #import <UIKit/UIKit.h>
  10
  11 @interface adcViewController : UIViewController
  12
  13 @property (weak, nonatomic) IBOutlet UITextField *inputTxt;
  14 
  15 @end

Passe o mouse sobre o círculo na linha 13 e veja que o campo de texto no storyboard é selecionado, indicando esta ligação. A Figura 15 ilustra este procedimento.

Checagem da conexão
entre componente e objeto
Figura 15. Checagem da conexão entre componente e objeto.

Crie novos outlets para o Slider (0), Label da gorjeta (1), o campo de texto do valor da gorjeta (2), o campo de texto do valor total (3), o campo de texto do número pagantes (4), o Stepper (5) e o campo de texto do valor individual por pessoa (6), veja a Figura 16 e a Listagem 3 (linhas 13-20) para um auxílio sobre quais campos devem ser conectados e como os mesmos foram identificados.

Campos a serem conectados
Figura 16. Campos a serem conectados.

Listagem 3. Outlets criados.

  #import <UIKit/UIKit.h>
   
  @interface adcViewController : UIViewController
   
  @property (weak, nonatomic) IBOutlet UITextField *inputTxt;
  @property (weak, nonatomic) IBOutlet UISlider *slider; //(0)
  @property (weak, nonatomic) IBOutlet UILabel *labelGorjeta; //(1)
  @property (weak, nonatomic) IBOutlet UITextField *valorGorjeta; //(2)
  @property (weak, nonatomic) IBOutlet UITextField *valorTotal; //(3)
  @property (weak, nonatomic) IBOutlet UITextField *numPagantes; //(4)
  @property (weak, nonatomic) IBOutlet UIStepper *stepper; //(5)
  @property (weak, nonatomic) IBOutlet UITextField *valorPagantes; //(6)
   
  @end

Com os outlets criados, finalmente temos um meio de manipular os componentes gráficos via código, basta alterar os valores dos objetos e esta mudança irá refletir na view. Entretanto, é importante também criarmos ações para que possamos perceber os eventos de mudança de valor do Slider, usuário clicou no Slider e movimentou o mesmo, e mudança de valor do Stepper, o usuário clicou no botão mais ou menos do Stepper.

O processo para criar ações é similar ao de criação de outlets. Clique com o botão direito do mouse sobre o Slider e arraste a conexão entre o bloco dos outlets e a diretiva @end. A tela para criação é mostrada. Selecione Action como o tipo de conexão, nomeie de sliderMudou e verifique se o evento marcado é o de Value Changed, conforme ilustra a Figura 17. Faça o mesmo para o Stepper, mas nomeie a ação como stepperMudou, conforme apresenta a Listagem 4.

Criação de uma ação
Figura 17. Criação de uma ação.

Listagem 4. adcViewController.h com outlets e ações declaradas.

  9 #import <UIKit/UIKit.h>
  10 @interface adcViewController : UIViewController
  11
  12 @property (weak, nonatomic) IBOutlet UITextField *inputTxt;
  13 @property (weak, nonatomic) IBOutlet UISlider *slider; //(0)
  14 @property (weak, nonatomic) IBOutlet UILabel *labelGorjeta; //(1)
  15 @property (weak, nonatomic) IBOutlet UITextField *valorGorjeta; //(2)
  16 @property (weak, nonatomic) IBOutlet UITextField *valorTotal; //(3)
  17 @property (weak, nonatomic) IBOutlet UITextField *numPagantes; //(4)
  18 @property (weak, nonatomic) IBOutlet UIStepper *stepper; //(5)
  19 @property (weak, nonatomic) IBOutlet UITextField *valorPagantes; //(6)
  20
  21 - (IBAction)sliderMudou:(id)sender;
  22 - (IBAction)stepperMudou:(id)sender;
  23 - (IBAction)fimDeInput:(id)sender;
  24
  25 @end

Neste momento temos a view pronta e os outlets conectados, faltando apenas implementarmos o controller com as ações a serem executadas. Para isto abra o arquivo adcViewController.m. Todo o arquivo .m apresenta a implementação de uma classe. Neste arquivo, conforme mostra a Listagem 5, encontramos na linha 9 a importação do .h equivalente, para que o .m possa reconhecer os objetos e ações declaradas, o método viewDidLoad, na linha 17, que é executado assim que a view é carregada, o método didReceiveMemoryWarning, na linha 23, que é executado caso haja algum problema de memória, e as nossas ações a serem implementadas, linhas 29 e 32.

Listagem 5. adcViewController.m.

  9 #import "adcViewController.h"
  10 
  11 @interface adcViewController ()
  12 
  13 @end
  14 
  15 @implementation adcViewController
  16 
  17 - (void)viewDidLoad
  18 {
  19     [super viewDidLoad];
  20        // Do any additional setup after loading the view, typically from a nib.
  21 }
  22
  23 - (void)didReceiveMemoryWarning
  24{
  25     [super didReceiveMemoryWarning];
  26     // Dispose of any resources that can be recreated.
  27 }
  28 
  29 - (IBAction)sliderMudou:(id)sender {
  30     
  31 }
  32 
  33 - (IBAction)stepperMudou:(id)sender {
  34    
  35 }
  36 
  37 @end

Execute o aplicativo e tente entrar com valores para a conta. Note que ao clicar no campo de texto da conta, o teclado é mostrado. Entre com valores numéricos e pressione a tecla return do teclado no simulador. Veja que o teclado não desaparece. Isto acontece porque não avisamos ao campo de texto da conta que ao clicar no return do teclado queremos que este campo perca o foco e o teclado desapareça. Para tal, vincule mais uma ação entre o storyboard e o adcViewController.h. Abra o storyboard e o Assistant Editor e vincule a ação fimDeInput ao evento Did End On Exit do campo de texto da conta. Tenha certeza de selecionar como o evento necessário o Did End On Exit, não use o evento padrão Editing Did End, conforme ilustra a Figura 18.

Evento para esconder o teclado
Figura 18. Evento para esconder o teclado.

Na ação fimDeInput devemos inserir um comando para que o campo de texto da conta perca o foco e dispense o teclado. A linha 36 da Listagem 6 mostra este comando. Note que ObjC usa passagem de mensagens para chamar os métodos ou ações a serem executadas. Neste caso, estamos informando ao alvo, o objeto inputTxt que execute a ação resignFirstResponder, que faz com que o mesmo perca o foco e dispense o teclado. A palavra self antes do objeto inputTxt indica que este objeto pertence a classe em questão. Execute novamente o aplicativo e verifique se o teclado é dispensado ao clicar no return.

Listagem 6. Escondendo o teclado.

  - (IBAction)fimDeInput:(id)sender {
      [self.inputTxt resignFirstResponder];
      [self atualizaResultados];
  }

Vamos agora implementar a lógica para que possamos calcular os valores finais baseados na entrada do usuário. O primeiro passo é saber quanto de gorjeta nosso usuário deseja deixar para o garçom. Esta informação está no Label da gorjeta, mapeado no objeto labelGorjeta. Este objeto deve ter seu valor alterado toda a vez que o usuário mudar o slider, portanto podemos atualizar o valor do labelGorjeta dentro da ação sliderMudou, conforme mostra a Listagem 7.

A linha 30 declara uma nova string chamada valorGorjeta que continua ao capturar o valor do slider (self.slider.value) e transformando-a para string, já que o mesmo retorna com um valor real (float). O método stringWithFormat inicializa a string valorGorjeta para que a mesma receba um valor float sem nenhuma casa decimal. Por fim, na linha 32, o labelGorjeta recebe o valor do slider. Execute o aplicativo e verifique as mudanças de valores neste label movendo o slider para esquerda ou direita.

Cuidado para o labelGorjeta não sobrescrever o símbolo de % na view, caso aconteça apenas aumente o espaçamento entre estes Labels.

Listagem 7. Capturando o valor do slider.

  - (IBAction)sliderMudou:(id)sender {
      NSString *strGorjeta =
          [NSString stringWithFormat:@"%.0f", self.slider.value];
      self.labelGorjeta.text = strGorjeta;
  }

Vamos fazer algo similar agora para capturar a mudança do valor do Stepper e atualizar o campo de texto correspondente. Implemente o método stepperMudou, no arquivo adcViewController.m, conforme a Listagem 8. Execute o aplicativo e verifique as mudanças de valores no campo do stepper.

Listagem 8. Método stepperMudou

  - (IBAction)stepperMudou:(id)sender {
      self.numPagantes.text =
          [NSString stringWithFormat:@"%.0f", self.stepper.value];
  }

Com a mudança do valor do slider e do stepper prontas, os campos de resultados também devem ser alterados, vamos criar um novo método que atualiza os campos necessários a partir de qualquer mudança na entrada de dados, seja no valor da conta, no valor do slider ou no stepper. Abra o adcViewController.h e acrescente a declaração do método atualizaResultados, conforme mostra a Listagem 9 (linha 26).

Listagem 9. Declaração do atualizaResultados no .h.

  - (IBAction)sliderMudou:(id)sender;
  - (IBAction)stepperMudou:(id)sender;
  - (IBAction)fimDeInput:(id)sender;
   
  - (void)atualizaResultados;
   
  @end

Implemente o método atualizaResultados, no arquivo adcViewController.m, conforme a Listagem 10. Note que o método mapeia o valor de entrada da conta para uma variável local float chamada conta. Depois é calculada a gorjeta, o total da conta e o total por pessoa.

Listagem 10. Implementação do método atualizaResultados.

  - (void) atualizaResultados {
      float gorjeta, conta, contaPorPessoa;
      conta = [self.inputTxt.text floatValue];
      gorjeta = [self.labelGorjeta.text floatValue] * conta / 100;
      self.valorGorjeta.text = [NSString stringWithFormat:@"%.2f", gorjeta];
      
      conta = conta + gorjeta;
      self.valorTotal.text = [NSString stringWithFormat:@"%.2f", conta];
      
      contaPorPessoa = conta / [self.numPagantes.text floatValue];
      self.valorPagantes.text = [NSString stringWithFormat:@"%.2f", contaPorPessoa];
  }
   
  @end

Para finalizar o aplicativo falta apenas a chamada deste método nas seções de entrada de dados, para tal acrescente o comando de chamada a este método ao final das ações fimDeInput, sliderMudou e stepperMudou. O comando de chamada é: [self atualizaResultados]. A Listagem 11 mostra o código para o arquivo adcViewController.h completo e a Listagem 12 para o arquivo adcViewController.m.

Listagem 11. adcViewController.h completo.

  #import <UIKit/UIKit.h>
   
  @interface adcViewController : UIViewController
   
  @property (weak, nonatomic) IBOutlet UITextField *inputTxt;
  @property (weak, nonatomic) IBOutlet UISlider *slider; //(0)
  @property (weak, nonatomic) IBOutlet UILabel *labelGorjeta; //(1)
  @property (weak, nonatomic) IBOutlet UITextField *valorGorjeta; //(2)
  @property (weak, nonatomic) IBOutlet UITextField *valorTotal; //(3)
  @property (weak, nonatomic) IBOutlet UITextField *numPagantes; //(4)
  @property (weak, nonatomic) IBOutlet UIStepper *stepper; //(5)
  @property (weak, nonatomic) IBOutlet UITextField *valorPagantes; //(6)
   
  - (IBAction)sliderMudou:(id)sender;
  - (IBAction)stepperMudou:(id)sender;
  - (IBAction)fimDeInput:(id)sender;
   
  - (void)atualizaResultados;
   
  @end

Listagem 12. adcViewController.m completo.

  #import "adcViewController.h"
   
  @interface adcViewController ()
   
  @end
   
  @implementation adcViewController
   
  - (void)viewDidLoad
  {
      [super viewDidLoad];
              // Do any additional setup after loading the view, typically from a nib.
  }
   
  - (void)didReceiveMemoryWarning
  {
      [super didReceiveMemoryWarning];
      // Dispose of any resources that can be recreated.
  }
   
  - (IBAction)sliderMudou:(id)sender {
      NSString *strGorjeta =
          [NSString stringWithFormat:@"%.0f", self.slider.value];
      self.labelGorjeta.text = strGorjeta;
      [self atualizaResultados];
      
  }
   
  - (IBAction)stepperMudou:(id)sender {
      self.numPagantes.text =
          [NSString stringWithFormat:@"%.0f", self.stepper.value];
      [self atualizaResultados];
  }
   
  - (IBAction)fimDeInput:(id)sender {
      [self.inputTxt resignFirstResponder];
      [self atualizaResultados];
  }
   
  - (void) atualizaResultados {
      float gorjeta, conta, contaPorPessoa;
      conta = [self.inputTxt.text floatValue];
      gorjeta = [self.labelGorjeta.text floatValue] * conta / 100;
      self.valorGorjeta.text = [NSString stringWithFormat:@"%.2f", gorjeta];
      
      conta = conta + gorjeta;
      self.valorTotal.text = [NSString stringWithFormat:@"%.2f", conta];
      
      contaPorPessoa = conta / [self.numPagantes.text floatValue];
      self.valorPagantes.text = [NSString stringWithFormat:@"%.2f", contaPorPessoa];
  }
   
  @end

A Figura 19 ilustra o aplicativo funcionando com um exemplo no qual a conta é de R$100,27, sendo que a gorjeta calculada é de R$15,04, o valor total da conta é de R$115,31 e o total por pessoa é de R$28,83.

Exemplo do aplicativo
funcionando no simulador
Figura 19. Exemplo do aplicativo funcionando no simulador.

Conclusão

Este artigo teve por objetivo apresentar conceitos básicos de programação para iOS. O projeto apresentado é um assistente de conta, que visa a partir do valor da conta do restaurante/bar, informar ao usuário o valor da gorjeta, o valor total da conta (gorjeta + entrada inicial) e o valor por pessoa. A gorjeta e o número de pessoas pagantes também podem ser customizadas pelo usuário.

Com este artigo o leitor pode conhecer um pouco de Objective-C, do padrão de projetos MVC, do Xcode e de como desenvolver aplicativos Single View Application usando alguns dos componentes de interface de usuário mais comuns. A partir do conhecimento adquirido neste projeto acredito que o leitor esteja apto a desenvolver novos aplicativos de maneira autônoma.

Links Úteis

  • Aplicativos híbridos com Ionic:
    Veja como criar aplicativos de forma rápida, flexível e produtiva para a plataforma do Ionic.
  • Transformando layouts em código:
    Neste DevCast conheceremos algumas ferramentas que são utilizadas pelas equipes de design e programação para a criação e compartilhamento de layouts/protótipos, facilitando a comunicação entre as áreas.
  • O que é NF-e e NFC-e?:
    Neste curso você terá o primeiro contato com mundo dos emissores de documentos fiscais eletrônicos Brasileiros.

Saiba mais sobre iOS ;)

  • Bate-papo sobre mobile:
    Neste DevCast temos um bate-papo sobre o desenvolvimento de apps mobile. Falamos aqui sobre quais tecnologias estudar, quando optar por cada uma e o que o mercado espera do desenvolvedor atualmente.
  • Como publicar seu app iOS na App Store:
    Neste curso você aprenderá a publicar seu aplicativo iOS na App Store, disponibilizando-o para que seus usuários possam fazer download e instalá-lo em seus dispositivos.
  • Introduzindo o framework Contacts do iOS 9:
    Este artigo apresenta o framework Contacts do iOS 9, a nova maneira de acessar e manipular os contatos no iOS.

Links

Developer Apple
http://developer.apple.com