« Febrero 2008 | Inicio | Abril 2008 »

Marzo 19, 2008

Uso de Core Animation para modificar el contenido de una vista

Uno de los frameworks que han hecho su debut con Leopard ha sido Core Animation.

Según Apple, Core Animation es un framework para renderizado gráfico, proyección y animación. Lo que, traducido, quiere decir, que es un framework que facilita enormemente la animación de elementos de interfaz.

Por ejemplo, es muy sencillo cambiar en tiempo de ejecución el contenido de una vista, sustituyéndolo por otra vista completamente distinta, presentando el cambio con una animación discreta, pero efectiva para reforzar el feedback que recibe el usuario del proceso.

En este ejemplo vamos a partir de este primer estado:

swap_final_1.png

Para llegar a este otro:

swap_final_2.png

Como puede verse, en este caso el cambio no es muy grande, se pasa de un slider a un desplegable, no obstante, la transición se hará utilizando la animación por defecto del framework (dissolve).

Construir el interfaz de la aplicación es sencillo. En la ventana principal de la misma, voy a colocar un botón, que será el que lance la animación, y una instancia de NSView, cuyo contenido iré modificando en tiempo de ejecución. Éste sería el aspecto de mi ventana:

swap_ventana.png

Además, construyo dos instancias más de NSView:

swap_view1.png

swap_view2.png

Como se puede ver, el ancho de las dos vistas es diferente.

Construyo también el esqueleto del controlador de la aplicación. Tendré tres outlets, uno a cada uno de las tres vistas (la de la ventana principal, y las dos vistas independientes). Además, tendré un action para el botón de "swap" y un booleano que me indicará si la vista que se está mostrando en cada instante es la primera o la segunda:

#import


@interface ViewSwapController : NSObject
{
IBOutlet NSView *containerView;
IBOutlet NSView *firstView;
IBOutlet NSView *secondView;

BOOL showFirst;
}

-(IBAction) swapView: (id) sender;
@end

Tras crear la instancia de NSObject en Interface Builder y asignarle como clase mi controlador, la estructura del nib sería como la siguiente:

swap_nib.png

Quiero que mi controlador haga lo siguiente: al arrancar la aplicación, insertará dentro de la vista de la ventana principal la primera de las dos vistas independientes que he creado, y cuando se haga clic en el botón de "swap" se cambiará esa vista por la segunda.

Por tanto, el método awakeFromNib será:

-(void) awakeFromNib
{
showFirst = NO;

[ containerView setWantsLayer: YES ];

[ [ containerView animator ] addSubview: firstView ];
}

Simplemente, preparo la vista de la ventana principal para que sea animable, y le añado como subvista la primera de mis vistas personalizadas.

Al hacer clic en el botón:

-(IBAction) swapView: (id) sender
{
NSRect containerFrame = [ containerView frame ];
NSRect firstViewFrame;
NSNumber *newCoord;
NSView *tempFirst;
NSView *tempSecond;

if( showFirst )
{
tempFirst = secondView;
tempSecond = firstView;

showFirst = NO;
}
else
{
tempFirst = firstView;
tempSecond = secondView;

showFirst = YES;
}

[ [ containerView animator ] replaceSubview: tempFirst with: tempSecond ];

firstViewFrame = [ tempSecond frame ];

newCoord = [ NSNumber numberWithFloat: containerFrame.size.width /2 - firstViewFrame.size.width/2 ];

[ tempSecond setFrameOrigin: NSMakePoint( [ newCoord intValue ] , 0 ) ];

}


En primer lugar, calculo el ancho de la vista contenedor, y de la vista que quiero colocar dentro de la misma, para luego poder centrarla, y posteriormente reemplazo la vista que esté dentro del contenedor por la que corresponda.

Lo importante, lo que hace que la transición entre las dos vistas sea animada, es que no ataco directamente la vista contenedor para modificar su contenido, sino que utilizo el decorator que crea CoreAnimation (que se llama animator) para que, de esa forma, cualquier modificación de las propiedades de esa vista se muestre de forma animada.

El proyecto puede descargarse del repositorio público de subversion:

svn co http://svn.liadorasoft.com/viewswap ViewSwap

Enlaces relacionados:
Un clon de Photo Booth en 32 minutos
Extensión por delegación
Bindings, NSArrayController y Value Transformers

Marzo 07, 2008

iPhone SDK

Ya está, ya hay un SDK para el iPhone/iPod Touch. Por fin se van a poder desarrollar y distribuir aplicaciones de forma "oficial", soportada por Apple y sin necesidad de hacer nada estraño con el aparato.

Desde mi punto de vista, como parte interesada, como usuario y como desarrollador, hay varias cosas que me han llamado la atención.

¿Documentación?
En primer lugar, la mayor sorpresa ha sido lo bien documentada que está la plataforma, sobre todo teniendo en cuenta que Apple tiende a producir una documentación más bien opaca, que es poco más que una enumeración de los interfaces de sus APIs.

Esta vez no sólo se han publicado documentos "en papel" sino una serie de vídeos en ADC on iTunes que sobrepasan con creces, en calidad de contenidos, lo que había disponible hasta ahora (exceptuando las sesiones de la WWDC). Lo que me lleva a pensar dos cosas más.

No es el iPhone ni el iPod, es lo que está por venir
La sensación, al menos la que yo tengo, es que lo que se documenta no es sólo el SDK para iPhone e iPod Touch, sino que lo se documenta es la plataforma de Apple para dispositivos con pantalla táctil.

Es decir, que la sensación que a mí me ha quedado es la de que lo que se abre hoy no es la puerta al desarrollo para un cacharro, sino para muchos, que compartirán ciertos frameworks. Conociendo la arquitectura de los frameworks de Apple no es nada descabellado pensar que este SDK mañana sirva para desarrollar aplicaciones para el sistema de control de un coche, o para un tablet, o para lo que sea que se pueda manejar con los dedos.

Y eso está muy bien.

Cuota de mercado
La otra conclusión es que esta plataforma (la llamémosla móvil) no tiene las limitaciones en cuanto a cuota de mercado que tiene un Mac. Apple lo sabe, y le da la importancia pertinente al SDK. D e hecho, se ha dividido el Developer Connection en dos partes jerárquicamente igual de importantes: el iPhone Developer Program, y el Mac Developer Program.

Sinceramente, llama la atención ver el esfuerzo que ha puesto Apple en facilitar a los desarrolladores la adaptación a esta plataforma.

Eso es, obviamente, bueno. Cuantos más sean (o seamos) desarrollando aplicaciones, mejores aplicaciones habrá. Lo que lleva al siguiente punto.

Modelo de distribución
Sinceramente, no me parece mal que las aplicaciones se distribuyan vía iTunes. No me tengo que preocupar de montar la web del producto, ni un sistema de cobro on-line, y más importante aún, mi aplicación está disponible para mis futuros usuarios desde el mismo dispositivo en el que se va a utilizar. Lo que va en la línea de actuación de Apple, por cierto, que no es otra que poner lo más fácil posible a la gente que pueda comprar. Y si yo quiero vender, y Apple lo pone fácil para comprar, la cosa me gusta.

Peeeeeeeeero, y siempre hay un pero, lo que no me gusta es que Apple tenga que aprobar la entrada de la aplicación en la tienda. Entiendo que ellos intentan proteger, por un lado, al proveedor de servicios móviles, y por otro, su propia reputación, pero eso tiene dos cosas muy malas, relacionadas: Apple puede decidir cerrar el paso a una aplicación porque le guste la idea, y puede decidir desarrollar una apliación similar por sí misma.

Lo de los 99$ por poder firmar aplicaciones y distribuirlas en la tienda de iTunes no me parece tan grave. Total, es lo que me iba a costar el hosting. Lo mismo pasa con el 30% de comisión que se queda Steve. Es alta, es cierto, pero tampoco es tan grave.

Lo que sí que toca las canicas es el empeño que tiene Apple en poner una línea entre usuarios/desarrolladores de USA y del resto del mundo. Que, digo yo, que algún día se nos va a acabar la paciencia.

El flujo de trabajo
Lo primero que me ha llamado la atención del SDK es que el emulador funciona muy bien. Lo segundo es que, por favor, hace falta un Interface Builder específico, que para hacer layouts a mano ya existe Java.

Poco más se puede decir, la verdad. Las herramientas son las de siempre, el lenguaje es el de siempre (aunque, ojo, sin recolector de basura, así que hay que volver al hold me - use me - release me) y todo es como siempre.

Sólo que, esta vez, con muchísima más expectación que otras veces.

Ahora, ya, sólo queda empaparse por completo de la documentación, y comprobar si, por favor, finalmente ha entrado en el SDK público el acceso a los SyncServices...