Sobre...

En este tutorial aprenderemos a desarrollar una aplicación desde cero: haremos un visor de imágenes!!
La aplicación tendrá una Vista y un botón para abrir los archivos. El código para abrir archivos será muy simple, ya que la API de Cocoa tiene sus propias funciones para abrir y mostrar archivos de imágenes. Podremos abrir muchos formatos, tales como: jpg, tga, gif (incluso animados!!), psd (!!) y algunos más.

Crear el proyecto

Primero crearemos el proyecto, nada que no hayamos visto hasta ahora:
- Abre el Xcode
- Ves a File -> New Project
- Selecciona "Cocoa Application" -> Next
- Escoge un nombre (por ejemplo: "Image Viewer"), selecciona un nombre para el directorio y pulsa en "Finish", esto creará un proyecto en blanco:

Editar la Interfaz con el Interface Builder

- Abre el Interface Builder, haciendo doble click en el archivo llamado "MainMenu.nib" file (que es un archivo que se ha generado automáticamente antes).
- En las preferencias de ventana (en el Inspector), selecciona "Has texture" (bueno, esto puedes hacerlo si tu quieres, no es necesario :) ). Ah! acuérdate de asignar un nombre (Window Title) a tu ventana (por ejemplo, Image Viewer).
Ahora pon un botón, este botón lo usaremos para abrir los archivos, de manera que la vista en diseño de la aplicación podría parecerse a esto:
- Ahora añade un control del tipo "Image View", esta "vista" la usaremos para mostrar las imágenes que cargaremos.
- Ahora guarda, compila y ejecuta la aplicación. Ahora, prueba a redimensionar la ventana... hey! esto es una mierda!! seguramente te has dado cuenta que los elementos de nuestra aplicación no se están redimensionando acorde con la ventana. Para poder redimensionar los elementos automáticamente tenemos que ajustar su tamaño.
- Vuelve al Interface Builder, selecciona el botón, y en el la ventana de propiedades del Inspector, selecciona la propiedad "size" (en el menú desplegable). Ahora ajusta los parámetros de "autosizing" tal y como ves en la imagen:
Los parámetros de autoredimensionado (autosizing) cambian el tamaño del botón acorde con las dimensiones de la ventana: Si redimensionamos la ventana horizontalmente, el botón también se redimensionará, pero si redimensionamos la ventana verticalmente, el botón permanecerá en la misma posición (arriba), y con el mismo tamaño.
Ahora ajustaremos los parámetros para el control "Image View", tal y como puedes ver en la imagen:

Crea la clase de control de la GUI (Control GUI)

Necesitamos crear una clase que controle los mensajes enviados por nuestra aplicación, necesitamos una Action que será llamada al seleccionar el fichero a abrir, y después necesitaremos crear 2 Outlets, uno para mostrar la imagen en el control Image View y el otro que se encargará de redimensionar la ventana principal según el tamaño de la imagen.
1- Selecciona el menú "Classes" (en el Interface Builder), y haz una subclase de la clase NSObject, ponle en nombre "GUIControl":
2- Crea los Outlets y las Actions, 2 Outlets (MyWindow y ViewImage) y 1 Action (openFile). Recuerda que los Outlets serán las variables que usaremos en nuestra clase para acceder a los contrles. Por ejemplo, si enlazamos (linkamos) "ViewImage" con nuestro control NSImageView, cada vez que modifiquemos el Outlet "ViewImage", el control NSImageView también se modificará:
3- Ahora añadiremos una instancia de nuestra clase al proyecto: Haz click derecho Right click (o ctrl-click) en la clase, y selecciona la opción "Instantiate GUIControl":
4- Aun tenemos que crear las conexiones entre los controles y nuestra clase:
4.1 - Conecta el botón de "Abrir" que hemos creado antes con la Action"openFile" de nuestra clase de control:
4.2 - Conecta la clase "GUIControl" con el control "Image View" y con el icono "Window". Queremos conectar la clase "GUIControl" con el icono "Window" ya que cada vez que abramos una imagen, redimensionará el tamaño de la ventana, de modo que tenemos que crear un enlace entre nuestra clase y la "Window" principal para poder tener acceso a las propiedades de la misma y cambiar su tamaño.
5- Finalmente, necesitamos crear los archivos de nuestra clase: en el menú "Classes", selecciona la clase "GIControl" y elige la opción "Create files for GUIControl":

A programar!!

1- Tenemos que añadir el código a nuestra clase para poder mostrar un diálogo estándar para abrir archivos y mostrar la imagen propiamente, de modo que los archivos de la clase GUIControl deberían tener un código como el siguiente:
Archivo: GUIControl.h
/* GUIControl */ #import @interface GUIControl : NSObject { IBOutlet NSWindow *MyWindow; IBOutlet NSImageView *ViewImage; } - (IBAction)openFile:(id)sender; @end
Archivo: GUIControl.m
#import "GUIControl.h" #define MAX_WIDTH 800 #define MAX_HEIGHT 600 @implementation GUIControl - (IBAction)openFile:(id)sender { // "Standard" open file panel NSArray *fileTypes = [NSArray arrayWithObjects:@"jpg", @"gif", @"png", @"psd", @"tga", nil]; int i; // Create the File Open Panel class. NSOpenPanel* oPanel = [NSOpenPanel openPanel]; [oPanel setCanChooseDirectories:NO]; [oPanel setCanChooseFiles:YES]; [oPanel setCanCreateDirectories:YES]; [oPanel setAllowsMultipleSelection:NO]; [oPanel setAlphaValue:0.95]; [oPanel setTitle:@"Select a file to open"]; // Display the dialog. If the OK button was pressed, // process the files. if ( [oPanel runModalForDirectory:nil file:nil types:fileTypes] == NSOKButton ) { // Get an array containing the full filenames of all // files and directories selected. NSArray* files = [oPanel filenames]; // Loop through all the files and process them. for( i = 0; i < [files count]; i++ ) { NSString* fileName = [files objectAtIndex:i]; NSLog(fileName); NSImage *imageFromBundle = [[NSImage alloc] initWithContentsOfFile:fileName]; if (imageFromBundle!=nil) { if ([ViewImage image]!=nil) [[ViewImage image] release]; [ViewImage setImage: imageFromBundle]; NSRect frame = [MyWindow frame]; frame.size = [imageFromBundle size]; if (frame.size.width >= MAX_WIDTH) frame.size.width = MAX_WIDTH; if (frame.size.height >= MAX_HEIGHT) frame.size.height = MAX_HEIGHT; frame.size.width += 80; frame.size.height += 150; [MyWindow setFrame:frame display:YES animate:YES]; } } } } @end
Comentemos el código más útil:
NSArray *fileTypes = [NSArray arrayWithObjects:@"jpg", @"gif",@"png", @"psd", @"tga", nil];
Aquí definimos un array de tipos de imágenes que nuestro panel será capaz de abrir (si, seremos capaces de abrir hasta archivos PSD!!).
Como es un array, el valor "nil" tiene que ser el último siempre.
NSOpenPanel* oPanel = [NSOpenPanel openPanel]; [oPanel setCanChooseDirectories:NO]; [oPanel setCanChooseFiles:YES]; [oPanel setCanCreateDirectories:YES]; [oPanel setAllowsMultipleSelection:NO]; [oPanel setAlphaValue:0.95]; [oPanel setTitle:@"Select a file to open"];
Aquí creamos un panel estándar para abrir archivos, después podemos ajustar algunos de sus parámetros, por ejemplo, si queremos añadir un botón para crear directorios directamente desde el panel (setCanCreateDirectories), o definir el nivel de transparencia del panel (setAlphaValue).
if ([oPanel runModalForDirectory:nil file:nil types:fileTypes]==NSOKButton)
Aquí definimos un condicional, entraremos solo si se pulsa el botón OK en el panel de abrir archivo, en caso contrario, no ejecutaríamos lo que viene a continuación.
Después procesamos los archivos seleccionados, la operación para abrir el archivo se hace con una sola función:
NSImage *imageFromBundle=[[NSImage alloc] initWithContentsOfFile:fileName];
Después, si la imagen se puede leer bien:
if ([ViewImage image]!=nil) [[ViewImage image] release];
Aquí verificamos si había una imagen previamente cargada en la memoria de la variable "ViewImage", en tal caso la liberamos (borramos memoria). Es importante liberar la memoria para prevenir los llamados memory leaks!
[ViewImage setImage: imageFromBundle];
Aquí fijamos la imagen de la variable "ViewImage". Recuerda que "ViewImage" es el Outlet de nuestra clase, y lo hemos conectado con el control NSImageView. En otras palabras, aquí fijamos la imagen que se verá en el control NSImageView.
NSRect frame = [MyWindow frame]; frame.size = [imageFromBundle size]; if (frame.size.width >= MAX_WIDTH) frame.size.width = MAX_WIDTH; if (frame.size.height >= MAX_HEIGHT) frame.size.height = MAX_HEIGHT; frame.size.width += 80; frame.size.height += 150; [MyWindow setFrame:frame display:YES animate:YES];
Con este código estamos modificando el tamaño de nuestra ventana, de manera que se ajuste al tamaño de la imagen que acabamos de abrir. Tenemos que respetar un tamaño máximo, para que nuestra ventana no sobrepase la resolución de la pantalla. También tenemos que incrementar el alto y ancho de nuestra ventana un poco, para poder dejar espacio para el botón que hemos añadido, y los marcos de la ventana. Con el parámetro "animate" estamos especificando que nuestra ventana se redimensionará con un efecto de animación muy molón :D

Compilar y listos!!!

Y eso es todo!! Simplemente compila y ejecuta la aplicación!!

Preguntas?

Alguna duda? envíame un email a xphere (en) zonan [punto] org

Creative Commons License
This tutorial is under a Creative Commons license.