Por Ivan Cantarino para o Pplware
Conforme mencionei anteriormente , hoje iremos aprender como utilizar verdadeiramente o nosso Xcode e respetiva linguagem de programação, Objective-C, com a iniciação da nossa App.
Como produto final iremos ter uma App simples, com uma caixa de texto, na qual podemos inserir o nosso nome, uma ‘caixa de saída’, onde nos é apresentado o texto inserido na caixa de texto, um botão de confirmação para que o texto inserido seja ‘aceite’ e seja devidamente apresentado e vamos aprender como fechar o teclado da nossa caixa de texto quando não o pretendemos usar mais.
Parece tudo uma coisa muito simples e básica, o que realmente é para os mais conhecedores do meio, mas como o objetivo é ensinar o mais simples possível para que os que se iniciam possam ter umas bases e consigam acompanhar o projeto devidamente e para que ninguém desista no primeiro teste, vamos iniciar algo simples e intuitivo.
Que Achas??
Para começar, vamos abrir o nosso projeto anteriormente criado, o PPLWAREApp.
Após estarmos com a aplicação aberta, podemos observar à nossa direita a biblioteca de objetos (Object Library), que nos dispõe objetos que podemos utilizar na nossa aplicação de forma simples e intuitiva.
Antes de selecionarmos qualquer objeto da nossa biblioteca, selecionamos primeiro o VIEWCONTROLLER.xib do nosso Project Navigator, na barra lateral esquerda, conforme foi apresentado no artigo anterior.
O ViewController.xib é a parte gráfica da nossa App, visto nos mostrar como ela se encontra inicialmente e deixa-nos adicionar objetos e ligações funcionais.
No ViewController.xib não é possível implementar código, para tal temos o ViewController.h (header) e o ViewController.m (implementation), que iremos usar mais adiante.
Tendo-o selecionado, podemos observar um género de aplicativo vazio, tendo somente no topo um layout com a bateria do iDevice (meramente ilustrativo), e uma tela em branco, pois nenhum objeto foi inserido.
Voltando à Object Library à esquerda, selecionamos o objeto Text Field (4 objeto a contar de cima para baixo), e clicamos fixamente no objeto e arrastamos para qualquer área do nosso iDevice no ViewController.xib.
Caso tenham alguma dificuldade em encontrar o Text Field podem sempre utilizar a caixa de pesquisa, situada no fim da Object Library, que facilita o encontro de determinados objetos, em vez de andarem com o scroll à procura.
Quando tiverem o Text Field na página da nossa aplicação podem ajustá-lo da forma que melhor entenderem, mediante o vosso projeto.
Como tal, eu vou centrá-lo no topo e aproveitar as linhas de ajustamento facilitadas pelo Xcode, para que não fique disforme como podem ver na imagem seguinte.
Para conseguirem este efeito basta usarem os pontos de arrasto\ajuste da própria caixa.
Avançando para o próximo objeto, inserimos uma LABEL, que normalmente serve como objeto de Output, ou seja, as mensagens escritas no Text Field (caixa de texto), quando processadas aparecem na LABEL (‘Caixa de saída’).
Após ‘arrastarem’ a LABEL para o nosso visualizador, processamos ao seu ajustamento da mesma forma que ajustamos o Text Field.
Quando a LABEL estiver devidamente ajustada, em baixo do Text Field, podemos clicar duas vezes em cima do texto ‘Label’ e apagamos o texto.
Agora podemos dar a parecer que a Label desapareceu, mas não, se clicarmos no espaço onde a dispusemos podemos ver os pontos de ajustamento aparecerem, portanto até agora tudo bem!!
Prosseguindo com a adição de objetos, vamos inserir, da mesma forma, um Round Rect Button, clicando e arrastando para um espaço vazio.
O Round Rect Button, serve maioritariamente como um botão de ação, ou seja, quando inserimos um texto e clicamos OK, esse OK pode ser um Round Rect Button.
Quando escrevemos uma mensagem e fazemos ENVIAR, esse ENVIAR pode ser também um Round Rect Button.
Em suma, um Round Rect Button é um botão ao qual podemos implementar as funções pretendidas quando clicamos nele, sendo que este pode ser ínfimas opções.
Da mesma forma anteriormente descrita, ajustamos o nosso botão alinhado ao centro da página.
Para tal, quando o estiverem a ajustar podem ver uma linha vertical no centro que define que este está precisamente alinhado com o centro da página.
Quando o nosso Round Rect Button estiver devidamente centrado, como podem ver na imagem, podemos alterar o seu nome de ‘Button’ para qualquer pretendido.
No meu caso vou nomeá-lo de ‘OK’, mas podem por o nome que vos apetecer, como por exemplo: Enviar, Feito, Concluído, etc…
Para realizar a alteração do seu nome o processo é semelhante ao de retirar o nome da Label, clicando duas vezes em cima do nome e quando o texto aparecer selecionado podem escrever o pretendido.
Podem igualmente alterar o tamanho do próprio botão, para que fique mais ajustado ao texto que inseriram.
Para que se possam enquadrar e ver o estado atual visual da nossa App, segue-se a imagem.
Agora vamos proceder às devidas implementações e ações dos objetos que inserimos, como tal, temos de os ‘dar a reconhecer’ aos nossos ficheiros de implementação.
Começamos por fechar a nossa barra lateral direita, para facilitar a visualização e ficarmos com mais espaço de trabalho, clicando no Hide do nosso Utilities Panel do separador VIEW.
Agora ficamos somente com o nosso ViewController.xib à vista, podendo assim abrir o Assistance Editor.
Nesta imagem o Assistance Editor é o símbolo do centro do primeiro trio de imagens.
Quando o Assistance Editor tiver aberto, podem confirmar se este abriu o ViewController.h, sendo que o texto que vos irá aparecer inicialmente deverá ser de:
//
//ViewController.h
//PplwareApp
…
Agora, conforme foi mencionado anteriormente, vamos dar a conhecer aos nossos ficheiros de implementação o nosso Text Field, a nossa Label e o Round Rect Button.
Para tal, começamos por dar um clique com o lado direito do rato (para quem usar o trackpad cliquem em Shift + Clique, que terá o mesmo efeito que o botão direito do rato) no nosso Text Field e arrastamos (aqui aparece uma linha azul no arrasto) a linha para o nosso Assistance Editor e largamos entre (no meio) os parâmetros @interface ViewController : UIViewController e @end.
Quando largamos a conexão, abre-nos um pequeno menu no qual é-nos mostrado determinadas opções de seleção, como mostra a figura.
Agora passo a explicar os devidos conteúdos deste pequeno menu que nos abre automaticamente após realizarmos a conexão.
- Connection -> Outlet (neste caso a conexão é uma Outlet, visto que a caixa de texto não irá realizar nenhuma ação em particular , somente após a inserção de texto a mesma vai mostrar o que nela introduzimos e enviará a função para a Label. Como ambos serão dispositivos de saída , as suas conexões são Outlets)
- Object -> File’s Owner (neste caso nada é alterado e com a função que realizamos de arrastar a conexão para o ViewController.h este vai ser ligado ao ficheiro mãe, por assim dizer)
- Name -> (Aqui é o local onde damos o nome à nossa Outlet, como noutras linguagens damos o nome a variáveis, aqui temos o ‘atalho’ para denominar tanto as Outlets como os Actions. Por força do hábito e porque a minha aprendizagem e formação foi maioritariamente em Inglês costumo denominar as variáveis e afins com nomes em Inglês, também porque toda a linguagem é processada em Inglês. Neste caso particular denominei a Outlet de myTextField, sempre em CamelCase. Podem nomear com qualquer outro nome, só que posteriormente quando for necessário implementar código, onde eu mencionar a Outlet pelo nome que defini vocês têm de alterar e por o nome que escolheram. Um outro pormenor importante é o uso de CamelCase, ou seja, as denominações que pretendemos têm de estar num texto contínuo sem espaços, por ex: Podia nomear a Outlet com o meu nome, mas não poderia ser de Ivan Cantarino, teria de ser IvanCantarino ou ivanCantarino ou ivancantarino. Como que por regra utiliza-se as iniciais em maiúsculas – os entendidos sabem do que falo)
- Type -> UITextField (User Interface Text Field, isto porque é um Text Field e este campo é sempre adicionado por ‘defeito’ consoante o Object que implementamos no Header File.)
- Storage -> Strong (este campo é igualmente adicionado por ‘defeito’ pelo que normalmente não necessitamos de nos preocupar muito. Quando as Outlets eram criadas manualmente, poderíamos especificar de as queríamos non-atomic, weak ou strong, mas com as versões mais recentes do Xcode não é necessário nos preocuparmos com tal, somente quem está mais integrado na matéria perceberá quando será necessário especificar o tipo de armazenamento pretendido para cada objeto.)
Visto isto clicamos em ‘Connect’ e a ligação irá piscar e estará concluída com sucesso.
Realizamos exatamente os mesmos passos para a nossa Label.
Neste caso nomeei-a de myLabel e clicando em Connect a ligação irá piscar e verificamos que a propriedade é criada.
Cada conexão criada em Outlet é criada uma propriedade conforme mencionei. Essas propriedades são adicionadas no nosso Header File (ficheiro com a extensão .h, exemplo o nosso ViewController.h) com a seguinte denominação:
@property (strong, nonatomic) IBOutlet UITextField *myTextField;
Explicando:
- @property – propriedade criada da Outlet
- strong, nonatomic – explicarei posteriormente se for necessário realizar alterações.
- IBOutlet – Interface Builder Outlet – identifica o tipo de Outlet criado.
- UITextField – objeto que foi usado para a Outlet
- *myTextField; – nome que demos à Outlet.
Realizando as conexões das duas Outlets, vamos realizar também a conexão do nosso botão OK.
Procedendo os mesmos passos conforme anteriormente realizamos a ligação e abrir-nos-á o mesmos menu, mas teremos de realizar neste umas pequenas alterações.
Como podem constatar na imagem, o Round Rect Button terá de ser alterado de Outlet para Action, pois pretendemos que quando este for premido realize uma devida ação, que será a de enviar o texto inserido na caixa de texto para a Label.
O nome que dei ao botão foi de myButton e o tipo é de UIButton, visto ser um botão o que neste caso não é necessário realizar alterações porque reconhece o objeto e fica corretamente definido automaticamente.
Visualizando o nosso ViewController.h após as conexões, este deverá ter o seguinte aspeto.
Provavelmente o vosso tema não terá a apresentação do meu, visto eu ter alterado a apresentação do mesmo nas definições. Desta forma consigo localizar-me mais facilmente pelas cores, sabendo que determinados parâmetros possuem determinadas cores. O importante aqui é os códigos de implementação estarem corretos.
Adiante!!
Atualmente o Xcode reconhece quando inserimos propriedades (@property) e faz a devida sintetização (@synthetize) das mesmas no implementation file (ficheiro com extensão .m).
Com a força de hábito e também por gosto pessoal, insiro o reconhecimento das minhas propriedades manualmente no Implementation File, pelo que vos vou ensinar este campo muito simples.
Primeiro cliquem em ‘Show the Standard editor’ no separador view (primeiro ícone da primeira série de três) e em seguida selecionem o ficheiro ViewController.m no nosso Project Navigator (barra da esquerda).
Podem constatar esta página com alguns comentários e algum código já pré-definido.
Deslocando verticalmente iremos encontrar o código @implementation no qual, tudo o que se encontra entre ele e o código @end faz parte dos processos de implementação.
Podemos constatar também que não temos nenhum @synthesize, de maneira que teremos de os inserir manualmente.
Para tal, clicamos em baixo do nosso @implementation (pode ser na linha mesmo a seguir) e vamos sintetizar as propriedades que criamos que ficaram da seguinte forma.
@synthesize myTextField;
@synthesize myLabel;
Duas coisas!! Nunca se esqueçam das sintetizações senão o implementation poderá não reconhecer as propriedades e após as suas parametrizações não se esqueçam do ponto e vírgula ( ; ).
Como objeto final ficará desta forma:
Com as propriedades sintetizadas, vamos proceder à implementação do nosso botão OK.
Para tal, vamos a baixo, até vermos o código
-(IBAction)myButton:(id)sender { }
e vamos inserir dentro das chavetas a informação\função que este botão vai desencadear quando for pressionado.
Começamos por inserir o seguinte comando dentro das chavetas ( { } ):
NSString *message = [[NSString alloc]initWithFormat:@”Olá %@”, [myTextField text]];
Confuso? É normal, mas passo a explicar o que acabamos de inserir.
Primariamente criamos uma String, ou seja, uma corrente.
Esta corrente é descrita inicialmente por NSString ( NS deriva de Next Step, empresa criada por Steve Jobs quando este saiu da Apple, empresa essa que foi adquirida posteriormente pela Apple quando Steve Jobs voltou a ser o CEO da marca da maçã. Assim sendo, o NS foi implementado no Objective-C como sua derivação) e após isso colocamos um asterisco e damos o nome pretendido à variável, que neste caso denominei de ‘message’.
Ficando assim NSString *message
O nome das variáveis são descritos com um asterisco antes do nome pretendido, daí estar escrito ‘*message’
Continuando com a explicação do comando que inserimos, a nossa corrente com o nome message terá de ser igual a algo.
Aqui damos um espaço, colocamos um igual ( = ) e damos novamente espaço e começamos a descrever o objetivo da nossa variável criada.
Neste caso abrimos dois parêntesis retos ( [[ ), sendo que para cada parêntesis , parêntesis reto ou chaveta abertos, temos de ter o mesmo número a fechar, para que o compilador entenda que todas as parametrizações estão devidamente enquadradas.
Identificamos o tipo de comando, neste caso o NSString e como tal, temos de criar a alocação da corrente, daí inserirmos o comando ‘alloc’.
Fechando um parêntesis reto, estamos a dizer que um processo imputado está terminado.
Continuando, e já que criamos uma corrente, demos-lhe um nome na variável e pretendemos que esta seja igual a algo, vamos implementar a sua iniciação com um formato específico.
Para tal, após encerrarmos o parêntesis reto inserimos o comando initWithFormat e damos dois pontos ( : ), ou seja, agora vamos especificar que tipo de iniciação pretendemos.
Neste caso particular, eu pretendo que o Text Field envie automaticamente para a Label uma determinada palavra, para que esta seja adicionada ao texto inserido manualmente.
A palavra em questão é ‘Olá’ e pretendo que o utilizador insira o seu nome na caixa de texto e prima OK.
Quando realizada a tarefa, o que irá ser disposto na Label será ‘Olá + nome’ e , para tal acontecer, a seguir aos dois pontos colocamos um arroba ( @ ) abrimos aspas ( “” ) e escrevemos Olá (ou algo que pretendam) e damos espaço antes de escrevermos dois símbolos juntos: %@ e fechamos aspas.
Nas mais comuns línguas de programação (daí ter mencionado anteriormente que seria aconselhável terem qualquer base no meio), identificamos as variáveis nas implementações com letras, depois fechamos as aspas, inserimos uma vírgula e identificamos a variável em questão.
No Objective-C não é diferente, simplesmente antes de inserirmos a letra que substitui a variável temos de inserir o sinal percentual ( % ) e em seguida a letra (posteriormente irei ensinar quais os tipos de letras para determinadas implementações pois podem ser utilizadas várias para cada especificidade).
Como os sinais %@ estão a substituir a variável, após fecharmos as aspas e colocarmos uma vírgula vamos identificar qual a variável que está a ser substituída, que neste caso é a variável da caixa de texto que nomeamos de myTextField , ficando assim identificada:
[myTextField text];
Neste caso, queremos que seja adicionado ao ‘Olá’ o texto inserido na variável myTextField, compreenderam?? Daí colocarmos a palavra ‘ text ‘ em frente à variável dentro dos parêntesis retos.
Para finalizar, temos de implementar o que a Label vai dispor , ou seja, identificarmos a Label como output message.
Para tal, damos uns Enter para criarmos mais espaço e inserimos o seguinte comando:
[myLabel setText:message];
Aqui estamos a dizer à variável da Label, neste caso nomeamos de myLabel, para que disponha\mostre o texto ( setText🙂 da variável message ( variável do NSString), compreenderam?
O processo é todo encadeado mutuamente para que o compilador compreenda o que pretendemos que cada variável faça.
Confirmando que têm tudo conforme foi descrito, o vosso ViewController.m deverá estar da seguinte forma:
Podemos agora correr a aplicação, para que a possam testar se tudo está perfeitamente funcional.
Cliquem em Run
Em seguida o iOS Simulator deverá abrir
Inserimos agora o nosso nome na caixa de texto e damos um OK no botão
(podem escrever com o teclado do Mac, não é necessário utilizar o teclado virtual, mas se assim o pretenderem tudo é funcional).
Podem verificar que na Label é apresentada a mensagem Olá + Nome inserido.
So far, So Good!!
Para terminar cliquem em qualquer área da tela.
Pois é… o teclado não fecha. Este é o último passo a concretizar.
Vou ensinar como fechar o teclado de três formas.
- Clicando em OK, a mensagem vai ser processada na Label e o teclado fecha automaticamente.
- Clicando em qualquer parte da tela da aplicação, o teclado desaparece.
- Clicando no botão RETURN do teclado este fechará também.
1º método:
A forma mais comum, e mais utilizada é o fecho automático do teclado quando clicamos em OK.
Para tal, voltamos ao nosso ViewController.m file, e descemos novamente até ao IBAction do botão e dentro das chavetas nativas deste, podendo dar uns Enter para criar mais espaço, inserimos o seguinte comando:
[myTextField resignFirstResponder];
O que acontece aqui é simples. A variável da nossa caixa de texto, vai detetar quando o botão é acionado e fará o Resign (fecho\demissão) do teclado à primeira resposta acionada, que neste caso é o acionamento do botão OK.
Ficando assim com o seguinte aspeto:
2º método:
Clicar em qualquer parte da tela.
Este ‘truque’, muito utilizado pelos devs, consiste em adicionar um novo Round Rect Button, fazendo que este faça o resign ao teclado quando for tocado.
Mas e então vamos por um botão novo a estorvar o ecrã? Perguntam vocês!!
Sim e não…
O botão vai lá estar, mas ninguém o vê, ficará invisível.
Para começar, abrimos o nosso ViewController.xib para adicionarmos um novo botão.
No nosso painel de objetos, procuramos o Round Rect Button e com um clique no botão direito do rato, ou Shift + Clique, arrastamos o botão para a nossa tela da aplicação.
Alteramos para Action e neste caso vou dar um nome português para constatarem que não faz qualquer diferença.
Chamei-o de sairTeclado
Feito isto, vamos ajustar o botão ao máximo, ou seja, com a largura total da tela.
Eh lá!!! Então onde está o nosso trabalho anterior??
Bom, agora vamos seguir estes passos.
Clicamos na barra superior em Editor -> Arrange -> Send to Back.
Assim o nosso botão foi enviado para trás dos outlets e do outro botão, mas mesmo assim é acionado sempre que tocamos na tela.
Agora no nosso Utilities Panel (barra esquerda), com o botão selecionado, clicamos em ‘ Show the Attributes inspector ‘ e alteramos o Type de Round Rect Button para Custom e o botão passa a ‘transparente’.
Agora, conforme feito anteriormente, vamos ao ViewController.m implementar o IBAction deste botão.
Procurando o IBAction certo implementamos dentro das chavetas o mesmo comando implementado anteriormente para fechar o teclado, ou seja,
[myTextField resignFirstResponder];
Ficando com a aparência final seguinte:
Para terminar esta aula morosa, vou ensinar o 3º método, sendo que este é o mais difícil, pois vamos utilizar Delegation.
Primeiro, continuando dentro do ViewController.xib, damos um clique na caixa de texto ( Text Field ) para que este fique selecionado.
Tendo o Utilities Panel aberto, damos um clique no último ícone, um que tem uma bola com uma seta a apontar para a direita dentro.
Ficando com o seguinte menu aberto:
Agora damos um clique na bola branca em frente ao Delegation e arrastamos a mesma para o File’s Owner, conforme descrito na imagem
Largamos o botão, este vai piscar.
Vamos abrir a biblioteca, que nos explica os Class Reference do Text Field.
Nas bibliotecas é-nos cedido algum sample code que é útil.
Vou ensinar neste caso, como utilizarem sample code disponível, para que posteriormente quando surgirem dúvidas saibam pesquisar e resolver os vossos entraves.
Ainda dentro do Utilities Panel, selecionamos o ícone ‘ Show Quick Help Inspector ‘ e em baixo em frente a ‘ Reference ‘ damos um clique em UITextField Class Reference, conforme a imagem.
Agora estando dentro da biblioteca, damos um clique em UITextFieldDelegate
Dentro desta nova página, fazemos um Scroll para baixo até encontrarmos o título textFieldShouldReturn que podem ler que esta função pergunta ao Delegate, neste caso adicionamos o delegation ao Text Field, o que fará quando o botão Return é pressionado.
Estando bem encaminhados podemos copiar a função\implementação que nos é cedida:
(BOOL)textFieldShouldReturn:(UITextField *)textField
Tendo este comando copiado, podemos fechar o Library e voltar ao ViewController.m e podemos colar este comando (ou inserir manualmente) em qualquer parte do @implementation e antes do @end claro.
Após este realização, abrimos uma chaveta em frente ao textField e implementamos o código para fechar o teclado:
[textField resignFirstResponder];
return YES;
E fechamos a chaveta [ para colocar chaveta pressionem simultaneamente alt+shift+ 8 ou 9 (abrir ou fechar)]
E pronto, podemos fazer o RUN à aplicação, verificar que o texto funciona corretamente, verificar que quando clicamos em OK o teclado fecha, quando clicamos na tela o teclado fecha e para finalizar, clicando em Return o teclado fecha igualmente.
Espero que tenham gostado desta aula, muito mais longa mas deveras necessária para aprendizagem.
Nunca desistam porque depois de aprenderem a programação torna-se apaixonante pois são capazes de criar algo único.
Acompanhem as próximas aulas.
Qualquer dúvida utilizem a caixa de comentários para as colocar que responderei com a maior brevidade possível.
Abraço a todos 😉