Aprendiendo Cocoa

Aplicacion Calculadora, parte 2

Octubre 21st, 2007 por admin

Tutorial creado con Xcode 2
Con esta segunda parte tratamos de dar fin a nuestra aplicación calculadora. Suponemos que todos habréis concluido con la parte 1 y os encontráis en esta situación.

Y para concluir, cread los archivos de nuestra clase Controlador, ya sabéis, pinchad en la pestaña Classes, botón derecho en nuestra clase y Create Files for Controlador, guardando los archivos junto al proyecto. Salvamos y cerramos Interface Builder, y nos vamos a por la segunda parte.

Ahora nos dirigimos hacia Xcode buscando en nuestro árbol del proyecto la carpeta Other Sources donde seguro que estarán nuestros archivos Controlador.h y Controlador.m. Ignoramos el Controlador.h debido a que es auto generado y es muy extraño que contenga errores y nos vamos al .m para implementar nuestras funciones.

Aquí os voy a enseñar un truco de Xcode, cada vez que queréis ver vuestros archivos, se os abrirán en una nueva ventana, algo incómodo si tienes varias abiertas. Pues pinchando en Editor, en la parte superior junto a Build, Build And Go… obligareís a nuestro IDE a abrir los archivos dentro de su ventana, siendo mucho mas ordenado y claro.

Volviendo al código, os comentó que es un código personal, cuya mejora me encantaría que mejorara entre todos, por lo que toda sugerencia es recibida, tanto de esta parte como de la primera. Primero para nuestro controlador necesitamos saber cual son los dos números y si la operación ha sido incluida para distinguir si estamos escribiendo en el primero o por el contrario es el segundo. Luego debajo de @implementation Controlador (pero antes que cualquier función) incluimos

int first_number;
int second_number;
int op=-1;

Nuestra primera función será la que se ejecuta nada mas despertar nuestra aplicación (awakefromNib) cuyo simple código es este.
- (void)awakeFromNib {
[text setStringValue:@"0"];
}

Simplemente incluye un 0 en el campo text. El resto de funciones son algo mas interesantes, como enterDigit
- (IBAction)enterDigit:(id)sender
{
NSArray *operaciones = [NSArray arrayWithObjects:@"+", @"-", @"*", @"/", nil];
if([operaciones indexOfObject:[text stringValue]]!=NSNotFound) {
//encontrado una operacion,la borramos
NSLog(@"borrando el contenido del text");
[text setStringValue:@""];
}
//solo un 0, no varios
if([text intValue]==0)
[text setStringValue:[NSString stringWithFormat:@"%d",[sender selectedTag]]];
else
[text setStringValue:[NSString stringWithFormat:@"%@%d", [text stringValue],[sender selectedTag]]];
}

En ella utilizamos un NSArray operaciones ( se inicializa siempre con nil como último elemento) con las operaciones permitidas y si la encuentra en el text significa que acaba de ser incluida una operación, con lo que borramos su contenido para luego introducir [sender selectedTag] en el. Esta función representa al tag que le asignamos a cada dígito, por lo que incluirá su tag correspondiente en el text. Para evitar incluir varios 0, antes preguntamos si contiene un 0 previamente. Para introducir texto en el NSTextField nos apoyamos de setStringValue para asignar el valor y de NSString stringWithFormat: para construir el NSString que incluimos con el formato que le sigue. Si no comprendéis este formato es muy parecido al C y también podéis consultarlo en el libro de MacProgramadores.

Luego tenemos en text un numero de una o varias cifras y de repente pulsamos algún signo de operación, con lo que gracias a las conexiones de InterfaceBuilder se ejecuta enterOp, cuyo código debéis copiar para que sea este.
- (IBAction)enterop:(id)sender
{
op=[sender selectedTag];
//el primero numero es el contenido actual
first_number=[text intValue];
NSLog(@"primer numero %d",first_number);
NSString* conversor;
switch ([sender selectedTag]) {
case 0:
//mas
conversor=@"+";
break;
case 1:
//-
conversor=@"-";
break;
case 2:
//por
conversor=@"*";
break;
case 3:
//div
conversor=@"/";
break;
default:
break;
}
//imprimimos el signo de la operacion cambiado
[text setStringValue:[NSString stringWithFormat:@"%@", conversor]];
}

Este código aunque es largo, es fácil de entender ya que solo guardamos el valor que tengamos en el outlet text dentro de first_number, guardamos la operación en op y convertimos el tag de la operación (acordaros que era 0,1,2 y 3) por su signo de operación. Con este signo ya convertido lo incluimos en el texto, borrando todo el contenido anterior.

Vamos que ya solo nos quedan dos, y es el turno de calculate, encargada de realizar la operación de la variable op, con first_number y el contenido actual del text que pasará a ser second_number.
- (IBAction)calculate:(id)sender
{
//el segundo numero es el contenido actual del text
second_number=[text intValue];
NSLog(@"segundo numero %d",second_number);
unsigned int result;
//evitar errores de division por cero
if(op==3 && second_number==0){
[text setStringValue:@"Error"];
}else{
switch (op) {
case 0:
//mas
result=first_number+second_number;
break;
case 1:
//-
result=first_number-second_number;
break;
case 2:
//por
result=first_number*second_number;
break;
case 3:
//div
result=first_number/second_number;
break;
default:
break;
}
//volvemos al principio e imprimimos el resultado
first_number=result;
[text setStringValue:[NSString stringWithFormat:@"%u",result]];
}
}

Guardamos el contenido del text ( mas bien su intValue) como second_number y nos ocupamos de la operación. En el caso que la operación sea 3 y el segundo numero un 0,tenemos un error que debemos mostrar, pero para el resto de los casos, con un switch tenemos suficiente. El código esta documentado para explicar lo que tratamos de hacer. Imprimimos el resultado en el StringValue de text pero previamente habiendo guardado el resultado en first_number para poder a volver a utilizarlo. El hecho que result sea un entero sin signo y utilicemos %u es para evitar conversiones extrañas en los números grandes.

Y la última función, enterC, la cual limpia el contenido del texto colocando un 0. Una función sencilla.

- (IBAction)enterC:(id)sender
{
op=-1;
NSLog(@"borrando el contenido del text");
[text setStringValue:@"0"];
}

Ahora solo nos queda Build and Go y listo. Espero que os funcione correctamente. Esta aplicación calculadora, no tiene signo unario, ni por ejemplo utiliza decimales como entrada ni como resultado, por lo que no es eficiente del todo. Os agradecería que entre todos tratemos de mejorarla y quien sabe si somos capaces de hacer una calculadora ligera pero completamente funcional. Muchas gracias y espero que lo hagáis aunque este ejemplo sea un poco mas complicado.

Posted in Cocoa

Una respuesta

  1. Jose

    Por lo menos esta tutorial está en xcode porque el que copia está todavía con Project Builder

Animate a dejar un comentario

Please note: Comment moderation is enabled and may delay your comment. There is no need to resubmit your comment.