1) Bajar e instalar el iOS4 SDK. (esto pueden hacerlo desde http://developer.apple.com/devcenter/ios/index.action )
2) Crear un nuevo proyecto con Xcode.
3) Definir un modelo, vista y controlador y conectarlos.
4) Usar Interface Builder para crear la interfaz gráfica
Parte 1
Crear un nuevo proyecto en Xcode
1. Abrimos /Developer/Applications/Xcode
2. En la pantalla que aparece seleccionamos create a new Xcode project
6. Volvemos a Xcode y podemos ver que hay un arbol de carpetas llamados Grupos y Archivos (Groups & Files). En este lugar es donde serán administrados todos los archivos.
En la sección Classes se crean automaticamente los archivos .h y .m para las dos clases CalculatorAppDelegate y CalculatorViewController. Por ahora no hay que preocuparse por CalculatorAppDelegate.
Parte 2
Crear una nueva clase para nuestro modelo
7. Para crear una nueva clase hacemos click en Groups & Files y seleccionamos New File ... desde el menú.
Parte 3
Definir las conexiones desde/hasta el controlador
Ahora que ya existen las clases de nuestro modelo hay que implementar nuestro controlador.
Comencemos definiendolo.
10. Hacer click en CalculatorViewController.h.
Vamos a ver una pantalla como la siguiente:
Notar que Xcode ha puesto el #import de la UIKit que necesitamos y ha hecho que
CalculatorViewController sea una subclase de UIViewController. Los Controladores son siempre directa o indirectamente subclases de UIViewController.
Nuestro archivo de cabecera todavía necesita que definamos lo siguiente:
a. outlets (variables de instancia en nuestro controlador que apuntan a objetos en nuestra vista)
b. actions (métodos en nuestro controlador que van a ser enviados desde la vista)
c. Una variable de instancia en nuestro controlador que apunta a nuestro modelo
11. Vamos a agregar el outlet que permite que nuestra CalculatorViewController hable con UILabel que representa el display en la vista. LLamaremos display a ese outlet.
Notar que la palabra clave IBOutlet no hace nada excepto identificar los oulets.
12. Ahora agregaremos una variable de instancia llamada brain que apunta desde nuestro Controlador hasta nuestro modelo CalculatorBrain. Necesitamos agregar un #import a CalculatorViewController.h para encontrar la declaración de CalculatorBrain.
Parte 4
Crear la Vista con el Interface Builder
No necesitamos escribir código sino que solo utilizaremos la herramienta Interface Builder. Cuando creamos un proyecto View-base Xcode automaticamente se crea un template . Este template se llama CalculatorViewController.xib (también denominado archivo nib, algunos lo llaman archivo zib ).
15. Abrir CalculatorViewController.xib.
16. Interface Builder tiene tres ventanas principales que contienen objetos o grupos de objetos. Es recomendable seleccionar Hide Others para ver que sucede en el Interface Builder.
La pantalla principal en el Interface Builder muestra todos los objetos de tu archivo .xib:
38. Y finalmente un método que nos permita realizar una operación.
39. Copiar la declaración de los dos métodos en CalculatorBrain.h, luego cambiar a CalculatorBrain.m y pegarlo entre @implementation y @end.
40. La implementación de setOperand: es facil. Lo que hacemos es darle el valor que viene como argumento a la variable de instancia.
41. La implementación de performOperation: también es simlple si el operando lo es, como por ej sqrt.
Veamos ahora un truco de debugging. Hay dos técnicas principales de debuging, una es utilizar el debugger que viene con el programa y la otra es usar printf, Objective-C provee la funcción NSLog() para esto. Vamos a utilizar NSLog() en operationPressed: y después vamos a ejecutar nuestra calculadora y ver en la consola el resultado.
El primer argumento es un NSString ( no una constante char *, por eso no olvidar @), y el resto de los argumentos son los valores para cualquier campo % en el primer argumento. Un nuevo tipo del campo % ha sido agregado, %@, que significa que el argumento correspondiente es un objeto.
47. Veamos este ejemplo con el método operationPressed:
Si hacemos click en un botón que realiza una operación nos aparecerá “The answer
to life, the universe and everything is 42.” ¿pero donde lo vemos?
48. Luego vamos al menú Run en Xcode y elegimos Console. Nos aparecerá una ventana. Ahí será donde veremos la salida. También se puede hacer click en Build and Run (o Build and Debug) en esa ventana para ejecutar el programa desde ahí. Hacemos click en una operación y deberíamos ver algo así:
50. Lo que necesitamos ahora es setear la variable Brain, para eso vamos a crear un método que cree y que retorne nuestra variable. Vamos a ponerlo justo antes de @implementation.
Basicamente queremos crear una variable brain, por eso hacemos la creación de la misma si esta no existe. Creamos la variable brain y la inicializamos.
51. Ahora que tenemos en el método CalculatorViewController.m que retorna a CalculatorBrain (nuestro Modelo) vamos a usarlo.
52. Tenemos el resultado de nuestra operación, solo necesitamos mostrarla en el display, para esto enviamos el mensaje setText: a nuestro display outlet (recuerden que esta ligado al UILabel en nuestra Vista View). El argumento que vamos a pasar es un NSString creado utilizando stringWithFormat:. Es como printf() o NSLog() pero para objetos NSString. Notar que estamos enviando un mensaje directamente a una clasee NSString (ni es una instancia de la clase sino la clase en si misma). Así es como creamos los objetos.
53. Volvemos a CalculatorViewController.h y agregamos la variable de instancia userIsInTheMiddleOfTypingANumber. Este tipo de dato es BOOL y es una versión del tipo de dato booleano en Objective-C’s . Puede tomar dos valores, YES or NO.
54. Ahora volvamos a CalculatorViewController.m y agregamos código a operationPressed: que lo que va a hacer es chequear si estamos tipeando un número y si es así actualizará el operando de CalculatorBrain para que sea el que ingreso el usuario (luego no sucedera más esto de estar en el medio del tipeo de un número).
Pero cuando se setea userIsInTheMiddleOfTypingANumber ? Bueno, se setea cuando el usuario empieza a ingresar dígitos. De todas maneras necesitamos implementar DigitPressed.
Pensemos en la lógica de este método. Hay dos situaciones diferentes cuando hacemos click sobre un dígito. El usuario puede estar ingresando un dígito, en este caso agregamos el dígito a lo que ya venia digitando o no y en este caso es cuando queremos mostrar en el display ese digito y hacer notar que estamos ingresando un número.
55. Agreguemos nuestra primera linea de código para digitPressed:. Nos va a retornar el dígito que fue presionado desde el titleLabel del UIButton que envio digitPressed:mensaje (el que envio).
56. Ahora que tenemos el dígito, lo agregamos a lo que ha sido tipeado (usando otro método NSString llamado stringByAppendingString:) o lo seteamos para que sea el nuevo número que estamos tipeando y hacer notar que comenzamos a tipear.
Quizas se pregunten si userIsInTheMiddleOfTypingANumber comienza con un NO.
Sí, lo hace porque los objetos que heredan de NSObject obtienen todas las instancias seteadas a cero. El cero para un valor del tipo BOOL es igual a NO. Hay que tener cuidado si el mensaje retorna un C struct (en este caso el resultado es indefinido).
Eso es todo, ahora deberíamos ejecutar nuestra aplicación y ver si no tenemos ningún error de sintaxis.
2. En la pantalla que aparece seleccionamos create a new Xcode project
También se puede crear un nuevo proyecto seleccionando New Proyect desde el menú.
3. En el dialogo que aparece hacemos click sobre View based Application
4. En la pantalla que se presenta hacemos lo siguiente:
- Navegamos hasta el lugar donde queremos mantener los proyectos para este curso
- En el campo Save as le ponemos el nombre Calculator
5. hacemos click en Save.
Ahora podemos ejecutar la aplicación aunque aparecerá la pantalla del simulador del iphone en blanco. Si todo esto funciona bien entonces el SDK se ha instalado correctamente :).
6. Volvemos a Xcode y podemos ver que hay un arbol de carpetas llamados Grupos y Archivos (Groups & Files). En este lugar es donde serán administrados todos los archivos.
En la sección Classes se crean automaticamente los archivos .h y .m para las dos clases CalculatorAppDelegate y CalculatorViewController. Por ahora no hay que preocuparse por CalculatorAppDelegate.
Parte 2
Crear una nueva clase para nuestro modelo
7. Para crear una nueva clase hacemos click en Groups & Files y seleccionamos New File ... desde el menú.
8. Hacemos click sobre Objective class (Subclase de NSObject) y después en el botón siguiente. Todos los objectos en Objective-C son subclases de NSObject.
9. Xcode preguntará por el nombre de la clase. Escribimos CalculatorBrain.m y dejamos chequeado la opción “CalculatorBrain.h” (Also create “CalculatorBrain.h” ) porque queremos ambos archivos, el de cabecera (.h) y el de implementación (.m) para nuestra clase CalculatorBrain class.
Nuestro Modelo ya ha sido creado. Vamos a dejar de lado el modelo y volvemos al controlador para escribir algunas declaraciones para las conexiones que necesitamos hacer entre la vista y el controlador.
Definir las conexiones desde/hasta el controlador
Ahora que ya existen las clases de nuestro modelo hay que implementar nuestro controlador.
Comencemos definiendolo.
10. Hacer click en CalculatorViewController.h.
Vamos a ver una pantalla como la siguiente:
Notar que Xcode ha puesto el #import de la UIKit que necesitamos y ha hecho que
CalculatorViewController sea una subclase de UIViewController. Los Controladores son siempre directa o indirectamente subclases de UIViewController.
Nuestro archivo de cabecera todavía necesita que definamos lo siguiente:
a. outlets (variables de instancia en nuestro controlador que apuntan a objetos en nuestra vista)
b. actions (métodos en nuestro controlador que van a ser enviados desde la vista)
c. Una variable de instancia en nuestro controlador que apunta a nuestro modelo
11. Vamos a agregar el outlet que permite que nuestra CalculatorViewController hable con UILabel que representa el display en la vista. LLamaremos display a ese outlet.
@interface CalculatorViewController : UIViewController { IBOutlet UILabel *display; } @end
Notar que la palabra clave IBOutlet no hace nada excepto identificar los oulets.
12. Ahora agregaremos una variable de instancia llamada brain que apunta desde nuestro Controlador hasta nuestro modelo CalculatorBrain. Necesitamos agregar un #import a CalculatorViewController.h para encontrar la declaración de CalculatorBrain.
#import <UIKit/UIKit.h> #import "CalculatorBrain.h" @interface CalculatorViewController : UIViewController { IBOutlet UILabel *display; CalculatorBrain *brain; } @end13. Y finalmente vamos a agregar dos acciones que la vista va a enviar cuando se presionen los botones.
@interface CalculatorViewController : UIViewController { IBOutlet UILabel *display; CalculatorBrain *brain; } - (IBAction)digitPressed:(UIButton *)sender; - (IBAction)operationPressed:(UIButton *)sender; @end
El único argumento de cada método es un objeto UIButton (el objeto le envia el mensaje a nuestro controlador cuando hace click sobre el mismo).
14. Compilamos y ejecutamos nuevamente la aplicación para saber si hay algún error. Seguramente hay advertencias porque los métodos no están implementados pero no hay problema con esto ya que son solo advertencias. Si aparece algún error se vera el circulo rojo como se ve en la imagen siguiente:
haciendo click sobre el error se muestra más información sobre el mismo.Ahora utilizaremos la herramienta gráfica para agregar un display algunos botones.
Parte 4
Crear la Vista con el Interface Builder
No necesitamos escribir código sino que solo utilizaremos la herramienta Interface Builder. Cuando creamos un proyecto View-base Xcode automaticamente se crea un template . Este template se llama CalculatorViewController.xib (también denominado archivo nib, algunos lo llaman archivo zib ).
15. Abrir CalculatorViewController.xib.
16. Interface Builder tiene tres ventanas principales que contienen objetos o grupos de objetos. Es recomendable seleccionar Hide Others para ver que sucede en el Interface Builder.
La pantalla principal en el Interface Builder muestra todos los objetos de tu archivo .xib:
El controlador CalculatorViewController es el File’s Owner . Por ahora ignoremos el objeto First Responder. El objeto View es la vista de más alto nivel, es la supervista de todas las vistas que tendremos en la interface. Todos los objetos UIView tienen una jerarquía en la cual cada uno tiene una superview y subviews. Otra de las ventanas es la librería que contiene todos los elementos necesarios para construir la vista. Por ahora vamos a usar dos UIButton and UILabel.
Otra de las ventanas es el inspector. El contenido de esta ventana cambia dependiendo que objeto este seleccionado.
17. Si hacemos click en File’s Owner en la pantalla principal, se debería ver esta pantalla:
La clase de tu File’s Owner debe ser CalculatorViewController. Lo próximo a realizar es poner algo en la pantalla de esta manera:
18. Comencemos con el dígito 7, localizamos en nuestra librería un botón Round Rect y simplemente lo arrastramos a la vista.
19. Modificamos el botón para que tenga 64 pixels de ancho.
20. La parte más importante es unir el botón con el CalculatorViewController (el File’s Owner en la pantalla principal) que es quien va a enviar el mensaje digitPressed: cuando hagan click sobre el botón. Para esto hay que hacer click en Ctrl y arrastrar una linea desde el botón hasta el Files Owner.
A medida que te acercas al File’s Owner, debe rodearlo una caja azul, cuando soltas el mouse debe aparecer una ventanita, selecciono en ella el metodo digitPressed:
22. Y ahora que ya tenemos hecha la conexión copiamos y pegamos los botones, todos ellos enviaran digitPressed.
23. Haciendo doble click sobre cada botón se le puede cambiar el nombre.
Ahora vamos a hacer las operaciones de los botones:
24. Arrastramos a la pantalla un botón.
25. Mantenga presionado Ctrl y arrastro una lines desde este nuevo boton hasta File’s Owner. Nuevamente va a aparecer la ventanita negra pero en este caso la operación va a ser operationPressed:.
26. Copiamos esto 5 veces (necesitaremos * / + - = y sqrt)
La interfaz debería verse de esta manera:
27. Arrastramos una etiqueta (UILabel) desde la librería, hacemos doble click y escribimos 0.
28. Seleccionamos la etiqueta.
29. Podes modificar las propiedades de los objetos como quieras como se ve en la siguiente imagen:
El CalculatorViewController necesita enviar mensajes al outlet para actualizarlo.
31. Arrastramos desde el File’s Owner to the UILabel.
32. Cuando soltamos el mouse debe aparecer la siguiente ventana. Selecciona display.
33. Guardamos el archivo de la Interface Builder y luego vuelvemos al Xcode.
34. Ejecutamos la aplicación.
Parte 5
Implementar el Modelo
El próximo paso es implementar el modelo CalculatorBrain.
35. Hacemos click en CalculatorBrain.h en la sección Groups & Files.
36. Primero nuestro modelo necesita un operando. Será un puntero flotante, entonces hagamos una variable de instancia que sea double.
double operand;
37. Ahora agreguemos un método que nos permita setear un operando.
- (void)setOperand:(double)aDouble;
38. Y finalmente un método que nos permita realizar una operación.
@interface CalculatorBrain : NSObject { double operand; } - (void)setOperand:(double)aDouble; - (double)performOperation:(NSString *)operation; @end
39. Copiar la declaración de los dos métodos en CalculatorBrain.h, luego cambiar a CalculatorBrain.m y pegarlo entre @implementation y @end.
// // CalculatorBrain.m // Calculator // // Copyright Stanford CS193p. All rights reserved. #import "CalculatorBrain.h" @implementation CalculatorBrain - (void)setOperand:(double)aDouble; - (double)performOperation:(NSString *)operation; @end
@implementation CalculatorBrain - (void)setOperand:(double)aDouble {} - (double)performOperation:(NSString *)operation {} @end
40. La implementación de setOperand: es facil. Lo que hacemos es darle el valor que viene como argumento a la variable de instancia.
- (void)setOperand:(double)aDouble { operand = aDouble; }
41. La implementación de performOperation: también es simlple si el operando lo es, como por ej sqrt.
- (double)performOperation:(NSString *)operation { if ([operation isEqual:@"sqrt"]) { operand = sqrt(operand); } return operand; }
El envío de mensajes a los objetos se hace entre corchetes. En este caso el mensaje es isEqual:.
Pensemos en operaciones con 2 operandos. Esto es un poco más dificil.
Imaginemos un usuario que interactua con la calculadora. El usuario ingresa un número,
luego una operacion, después otro número y despues presiona otra operación (o el igual) que es cuando espera que aparezca el resultado.
Si hace 12 + 4 sqrt = el resultado que se espera sera 14 y no 4. Las operaciones de 2 operandos deben ser retrasadas hasta la próxima operación o hasta que se presione el igual.
42. Volvemos a CalculatorBrain.h y agregamos 2 variables de instancias que necesitaremos para las operaciones de 2 operandos: una variable para la operación que esta esperando ser ejecutada hasta que se presione el otro operando y la otra para la siguiente operación.
43. Volvemos a CalculatorBrain.m. Esta es una implementación que soporta 2 operandos performOperation:
Basicamente si se le pide a CalculatorBrain que realice una operación que no es simple (código invocado por el else) entonces CalculatorBrain llama al método performWaitingOperation (que todavía no hemos escrito) para realizar waitingOperation
Todavía necesitamos implementar performWaitingOperation.
Cuando el mensaje es enviado a self significa que el mensaje se envia a si mismo. Otros lenguajes lo llaman this. performWaitingOperation es un método privado por lo tanto no lo pondremos en CalculatorBrain.h si no que ira en CalculatorBrain.m.
44. Esta es la implementación de performWaitingOperation. Es importante que este código lo pongas en tu archivo CalculatorBrain.m en alguna parte antes de la implementación de performOperation:.
Esto es porque performWaitingOperation es un método privado. No se encuentra en la API pública. Debe ser declarado o definido antes de ser usado en un archivo. El mejor lugar es quizás entre la implementación de setOperand: y la de performOperation:.
Usamos la sentencia if {} else para que waitingOperation pueda utilizarce con cualquier operación despues realizamos la operación usando el operando actual y el que estaba esperando (waitingOperand).
Nuestro modelo esta implementado. Lo único que nos falta es hacer el controlador.
Parte 6:
Implementar el controlador
Lo que nos falta codificar es lo que sucede cuando se presiona un dígito (digitPressed:) o una operación (operationPressed:). Este código ira en nuestro CalculatorViewController. Ya hemos declarado estos métodos en la cabecera archivo (.h) , pero ahora tendremos que hacer la implementación en el archivo .m.
45. Abrimos CalculatorViewController.m y seleccionamos y borramos todo el código de ayuda (“helpful” code) que se encuentra entre @implementation y @end.
46. Ahora volvemos a to CalculatorViewController.h y copiamos las dos declaraciones
de los métodos en CalculatorViewController.m entre @implementation y @end. Borramos los punto y coma y lo reemplazamos por { } (llaves vacías). Debería verse así:
Imaginemos un usuario que interactua con la calculadora. El usuario ingresa un número,
luego una operacion, después otro número y despues presiona otra operación (o el igual) que es cuando espera que aparezca el resultado.
Si hace 12 + 4 sqrt = el resultado que se espera sera 14 y no 4. Las operaciones de 2 operandos deben ser retrasadas hasta la próxima operación o hasta que se presione el igual.
42. Volvemos a CalculatorBrain.h y agregamos 2 variables de instancias que necesitaremos para las operaciones de 2 operandos: una variable para la operación que esta esperando ser ejecutada hasta que se presione el otro operando y la otra para la siguiente operación.
@interface CalculatorBrain : NSObject { double operand; NSString *waitingOperation; double waitingOperand; } - (void)setOperand:(double)aDouble; - (double)performOperation:(NSString *)operation;
43. Volvemos a CalculatorBrain.m. Esta es una implementación que soporta 2 operandos performOperation:
- (double)performOperation:(NSString *)operation { if ([operation isEqual:@"sqrt"]) { operand = sqrt(operand); } else { [self performWaitingOperation]; waitingOperation = operation; waitingOperand = operand; } return operand; }
Basicamente si se le pide a CalculatorBrain que realice una operación que no es simple (código invocado por el else) entonces CalculatorBrain llama al método performWaitingOperation (que todavía no hemos escrito) para realizar waitingOperation
- (double)performOperation:(NSString *)operation { if ([operation isEqual:@"sqrt"]) { operand = sqrt(operand); } else if ([@"+/-" isEqual:operation]) { operand = - operand; } else { [self performWaitingOperation]; waitingOperation = operation; waitingOperand = operand; } return operand; }
Todavía necesitamos implementar performWaitingOperation.
Cuando el mensaje es enviado a self significa que el mensaje se envia a si mismo. Otros lenguajes lo llaman this. performWaitingOperation es un método privado por lo tanto no lo pondremos en CalculatorBrain.h si no que ira en CalculatorBrain.m.
44. Esta es la implementación de performWaitingOperation. Es importante que este código lo pongas en tu archivo CalculatorBrain.m en alguna parte antes de la implementación de performOperation:.
Esto es porque performWaitingOperation es un método privado. No se encuentra en la API pública. Debe ser declarado o definido antes de ser usado en un archivo. El mejor lugar es quizás entre la implementación de setOperand: y la de performOperation:.
- (void)performWaitingOperation { if ([@"+" isEqual:waitingOperation]) { operand = waitingOperand + operand; } else if ([@"*" isEqual:waitingOperation]) { operand = waitingOperand * operand; } else if ([@"-" isEqual:waitingOperation]) { operand = waitingOperand - operand; } else if ([@"/" isEqual:waitingOperation]) { if (operand) { operand = waitingOperand / operand; } } }
Usamos la sentencia if {} else para que waitingOperation pueda utilizarce con cualquier operación despues realizamos la operación usando el operando actual y el que estaba esperando (waitingOperand).
Nuestro modelo esta implementado. Lo único que nos falta es hacer el controlador.
Parte 6:
Implementar el controlador
Lo que nos falta codificar es lo que sucede cuando se presiona un dígito (digitPressed:) o una operación (operationPressed:). Este código ira en nuestro CalculatorViewController. Ya hemos declarado estos métodos en la cabecera archivo (.h) , pero ahora tendremos que hacer la implementación en el archivo .m.
45. Abrimos CalculatorViewController.m y seleccionamos y borramos todo el código de ayuda (“helpful” code) que se encuentra entre @implementation y @end.
46. Ahora volvemos a to CalculatorViewController.h y copiamos las dos declaraciones
de los métodos en CalculatorViewController.m entre @implementation y @end. Borramos los punto y coma y lo reemplazamos por { } (llaves vacías). Debería verse así:
//CalculatorViewController.m //Calculator //Copyright Stanford CS193p. All rights reserved. #import "CalculatorViewController.h" @implementation CalculatorViewController - (IBAction)digitPressed:(UIButton *)sender { } - (IBAction)operationPressed:(UIButton *)sender { } @end
El primer argumento es un NSString ( no una constante char *, por eso no olvidar @), y el resto de los argumentos son los valores para cualquier campo % en el primer argumento. Un nuevo tipo del campo % ha sido agregado, %@, que significa que el argumento correspondiente es un objeto.
47. Veamos este ejemplo con el método operationPressed:
- (IBAction)operationPressed:(UIButton *)sender { NSLog(@"The answer to %@, the universe and everything is %d.", @"life", 42); }
to life, the universe and everything is 42.” ¿pero donde lo vemos?
48. Luego vamos al menú Run en Xcode y elegimos Console. Nos aparecerá una ventana. Ahí será donde veremos la salida. También se puede hacer click en Build and Run (o Build and Debug) en esa ventana para ejecutar el programa desde ahí. Hacemos click en una operación y deberíamos ver algo así:
49. Reemplacemos la implementación de NSLog(). Notar que el argumento para operationPressed: es el botón que nos esta enviando el mensaje. Le preguntaremos a quien nos envia el nombre del botón (titleLabel, los objetos UIButton usan objetos UILabel ) ,luego preguntamos el UILabel retornado para saber el texto. El resultado sera un NSString con un + ó * ó / ó - ó = ó sqrt.
- (IBAction)operationPressed:(UIButton *)sender { NSString *operation = [[sender titleLabel] text]; }
50. Lo que necesitamos ahora es setear la variable Brain, para eso vamos a crear un método que cree y que retorne nuestra variable. Vamos a ponerlo justo antes de @implementation.
- (CalculatorBrain *)brain { if (!brain) brain = [[CalculatorBrain alloc] init]; return brain; }
Basicamente queremos crear una variable brain, por eso hacemos la creación de la misma si esta no existe. Creamos la variable brain y la inicializamos.
51. Ahora que tenemos en el método CalculatorViewController.m que retorna a CalculatorBrain (nuestro Modelo) vamos a usarlo.
- (IBAction)operationPressed:(UIButton *)sender { NSString *operation = [[sender titleLabel] text]; double result = [[self brain] performOperation:operation]; }
52. Tenemos el resultado de nuestra operación, solo necesitamos mostrarla en el display, para esto enviamos el mensaje setText: a nuestro display outlet (recuerden que esta ligado al UILabel en nuestra Vista View). El argumento que vamos a pasar es un NSString creado utilizando stringWithFormat:. Es como printf() o NSLog() pero para objetos NSString. Notar que estamos enviando un mensaje directamente a una clasee NSString (ni es una instancia de la clase sino la clase en si misma). Así es como creamos los objetos.
- (IBAction)operationPressed:(UIButton *)sender { NSString *operation = [[sender titleLabel] text]; double result = [[self brain] performOperation:operation]; }
@interface CalculatorViewController : UIViewController { IBOutlet UILabel *display; CalculatorBrain *brain; BOOL userIsInTheMiddleOfTypingANumber; }
54. Ahora volvamos a CalculatorViewController.m y agregamos código a operationPressed: que lo que va a hacer es chequear si estamos tipeando un número y si es así actualizará el operando de CalculatorBrain para que sea el que ingreso el usuario (luego no sucedera más esto de estar en el medio del tipeo de un número).
- (IBAction)operationPressed:(UIButton *)sender { if (userIsInTheMiddleOfTypingANumber) { [[self brain] setOperand:[[display text] doubleValue]]; userIsInTheMiddleOfTypingANumber = NO; } NSString *operation = [[sender titleLabel] text]; double result = [[self brain] performOperation:operation]; [display setText:[NSString stringWithFormat:@"%g", result]]; }
Pero cuando se setea userIsInTheMiddleOfTypingANumber ? Bueno, se setea cuando el usuario empieza a ingresar dígitos. De todas maneras necesitamos implementar DigitPressed.
Pensemos en la lógica de este método. Hay dos situaciones diferentes cuando hacemos click sobre un dígito. El usuario puede estar ingresando un dígito, en este caso agregamos el dígito a lo que ya venia digitando o no y en este caso es cuando queremos mostrar en el display ese digito y hacer notar que estamos ingresando un número.
55. Agreguemos nuestra primera linea de código para digitPressed:. Nos va a retornar el dígito que fue presionado desde el titleLabel del UIButton que envio digitPressed:mensaje (el que envio).
- (IBAction)digitPressed:(UIButton *)sender { NSString *digit = [[sender titleLabel] text]; }
56. Ahora que tenemos el dígito, lo agregamos a lo que ha sido tipeado (usando otro método NSString llamado stringByAppendingString:) o lo seteamos para que sea el nuevo número que estamos tipeando y hacer notar que comenzamos a tipear.
- (IBAction)digitPressed:(UIButton *)sender { NSString *digit = [[sender titleLabel] text]; if (userIsInTheMiddleOfTypingANumber) { [display setText:[[display text] stringByAppendingString:digit]]; } else { [display setText:digit]; userIsInTheMiddleOfTypingANumber = YES; } }
Quizas se pregunten si userIsInTheMiddleOfTypingANumber comienza con un NO.
Sí, lo hace porque los objetos que heredan de NSObject obtienen todas las instancias seteadas a cero. El cero para un valor del tipo BOOL es igual a NO. Hay que tener cuidado si el mensaje retorna un C struct (en este caso el resultado es indefinido).
Eso es todo, ahora deberíamos ejecutar nuestra aplicación y ver si no tenemos ningún error de sintaxis.
Fuente: http://www.stanford.edu/class/cs193p/cgi-bin/drupal/downloads-2010-fall
Pdf en ingles: Assignment 1
Pdf en ingles: Assignment 1
5 comentarios:
Muy bueno!! Gracias, me re sirvio para empezar. Espero que sigas publicando
Para cuando la siguiente entrega?
De nuevo ánimo y gracias por tu trabajo.
Muchisimas gracias por hacer esto!
En verdad gracias por tu trabajo continua asi ahora estoy empezando a hacer esto
Saludos desde Mexico!!!!!
Gracias a todos por sus comentarios!!! ;)
Muy buen aporte hermano, buenisimopara empezar, cuando publicas material de acceso a datos? trabjar con xml? y funciones del telefono como el gps?
Publicar un comentario