miércoles, 26 de diciembre de 2012

Cómo cambiar la altura de UIPickerView

pickerview.transform = CGAffineTransformMakeScale(.5, 0.5);

viernes, 21 de diciembre de 2012

HSLUpdateChecker - Libreria que nos permite verificar cuando hay una nueva versión de nuestra App

Esta librería de Handelabra Studio que podemos agregar a nuestra aplicación nos permite chequear si hay una nueva versión disponible y si esto pasa nos muestra una alerta para poder bajarla. 

Pueden descargar HSLUpdateChecker desde aquí

miércoles, 12 de diciembre de 2012

SQLite Database Browser

SQLite Database Browser nos permite crear, editar y diseñar archivos de base de datos SQLite.
Podemos descargarla desde aquí http://sourceforge.net/projects/sqlitebrowser/ 

martes, 11 de diciembre de 2012

Ejercicios de punteros en C

Verificar si una cadena tiene caracteres unicos:



typedef enum{false, true} bool;

// Verificar si una cadena tiene caracteres unicos

bool hasUniqueCharacters(char *str)
{
    char *p = str;

    while (*str != '\0') {

        p++;

        if (*str == *p) {

            return false;
        }

        str++;
    }

    return  true;
}

int main(int argc, const char * argv[])
{
    if (hasUniqueCharacters("hola")) {

        printf("has unique");

    }else{

        printf("it doesnt has");
    }

    printf("Hello, World!\n");
    return 0;
}

lunes, 22 de octubre de 2012

Control Open Source para mostrar notificaciones similares a las de Android

Control inspirado en las notificaciones Toast de Android. El control permite  hacer simples alertas que pueden contener imagenes y  estar en diferentes posiciones.


Lo podemos encontrar en Github

martes, 2 de octubre de 2012

Recursos - UIAlertView Customizable

Este es un proyecto de Michael Zaborowski que nos permite customizar facilmente los AlertsViews, se puede elegir entre varios estilos, cambiar los títulos y el color.

El proyecto se puede bajar desde GitHub

domingo, 30 de septiembre de 2012

Convertir CFDictionaryRef en NSDictionary

CFDictionaryRef exifAttachments = CMGetAttachment( imageSampleBuffer, kCGImagePropertyExifDictionary, NULL); 
NSDictionary *andBack = (__bridge NSDictionary*)exifAttachments;

domingo, 2 de septiembre de 2012

viernes, 17 de agosto de 2012

ChipMunk - Librería de física 2D - Videojuegos para Iphone - Evaluando los resultados (Parte 7)

Evaluando los resultados

Todas estas reglas y este código tiene un objetivo que es la simulación de la físca. Puede ser que consigas lo mismo con la mitad de código pero veamos porque Chipmunk es la mejor opción:

Trata de cambiar la fricción de toda la forma del piso de 0.1 a 0.5. Ejecutemos el código, ahora la caida va a tener menos velocidad.

Traten de aumentar o decrementar la gravedad y/o la masa de la pelota. Traten de editar las formas un poco.
Finalmente, habrán notado que todas las formas tienen la propiedad de elasticidad pero no parece tener algún efecto en la simulación. Para habilitar la elasticidad del cuerpo hay que agregar el siguiente código después de setear la gravedad del espacio (el orden no importa siempre que obviamente haya sido creado el espacio):
// Agrega efecto elestico a la simulación 
  
space->elasticIterations = 10; 
Ahora si ejecutas la simulación y/o juegas con los valores de elasticidad de las formas veras que la pelota bouncing del suelo cuando cae.

Conclusión


Piensen que toma tiempo y esfuerzo entender como funciona Chipmunk además de los conceptos nuevos. En este tutorial espero haber sido claro en los principales conceptos de Chipmunk: espacio, cuerpos y formas.

ChipMunk - Librería de física 2D - Videojuegos para Iphone - Definiendo el cuerpo y la forma para el piso (Parte 6)

El piso necesita un cuerpo y una forma mas compleja. Crear el cuerpo es sencillo y solo tiene 2 detalles: su masa no importa y no la vamos a agregar a nuestro espacio. Esto puede sorprenderderlos pero si piensan por segundo se daran cuenta que el piso es estatico y por lo tanto no es necesario agregarle gravedad o un espacio. Por la misma razón configurar la masa estaría bien pero no tendría ningún efecto. Entonces, agregamos este código al final método setupChipmunk (También lo podemos agregar antes de la creación del cuerpo y forma de la pelota sin efectos negativos).
// Creamos el cuerpo del piso y le seteamos posición
  
cpBody *floorBody = cpBodyNew(INFINITY, INFINITY);  
  
floorBody->p = cpv(160, 480-350);

Entonces, ahora que tenemos el cuerpo necesitamos las formas. Hay muchas maneras de adjuntar la imagen, como comente en la sección de conceptos se puede agregar varias formas al cuerpo. En nuestro caso podemos crear varias lineas o definir un polígono. Realizaremos lo último porque es menos confuso si es que son nuevos en C. Los polígonos son poderosos pero tienen algunas restricciones en Chipmunk que deberían entender para poder aplicarlo de manera correcta. Lo primero que deben saber es que deberas proveer todos los vertices en el sentido de las agujas del reloj. Otra cosa que deben saber acerca de los polígonos en Chipmunk es que definen una forma convexa. Un poligono convexo es aquel donde la linea entre 2 puntos dentro de la forma sigue dentro de la forma.




Pueden buscar más información en Wikipedia o en este sitio.
// Definiendo los vertices de la forma
      
    cpVect verts1[] = { cpv(0.0, 0.0), cpv(50.0, 0.0), cpv(45.0, -15.0), cpv(0.0, -15.0) };  
      
    cpVect verts2[] = { cpv(50.0, 0.0), cpv(116.0, -66.0), cpv(110.0, -81.0), cpv(45.0, -15.0) };  
      
    cpVect verts3[] = { cpv(116.0, -66.0), cpv(204.0, -66.0), cpv(210.0, -81.0), cpv(110.0, -81.0) };  
      
    cpVect verts4[] = { cpv(204.0, -66.0), cpv(270.0, 0.0), cpv(275.0, -15.0), cpv(210.0, -81.0) };  
      
    cpVect verts5[] = { cpv(270.0, 0.0), cpv(320.0, 0.0), cpv(320.0, -15.0), cpv(275.0, -15.0) };  
Esto significa que si estas utilizando las imágenes que yo otorgué no seremos capaces de definir correctamente el piso solo con una forma. Para definirlo correctamente debemos utilizar 5 formas poligonales, vamos a definirlas.
    // Creando todas las formas 
      
    cpShape *floorShape = cpPolyShapeNew(floorBody, 4, verts1, cpv(-320.0f / 2, 81.0f / 2));  
      
    floorShape->e = 0.5; floorShape->u = 0.1; floorShape->collision_type = 0;  
      
    floorShape->data = floor;  
      
    cpSpaceAddStaticShape(space, floorShape);  
      
    floorShape = cpPolyShapeNew(floorBody, 4, verts2, cpv(-320.0f / 2, 81.0f / 2));  
      
    floorShape->e = 0.5; floorShape->u = 0.1; floorShape->collision_type = 0;  
      
    floorShape->data = floor;  
      
    cpSpaceAddStaticShape(space, floorShape);  
      
    floorShape = cpPolyShapeNew(floorBody, 4, verts3, cpv(-320.0f / 2, 81.0f / 2));  
      
    floorShape->e = 0.5; floorShape->u = 0.1; floorShape->collision_type = 0;  
      
    floorShape->data = floor;  
      
    cpSpaceAddStaticShape(space, floorShape);  
      
    floorShape = cpPolyShapeNew(floorBody, 4, verts4, cpv(-320.0f / 2, 81.0f / 2));  
      
    floorShape->e = 0.5; floorShape->u = 0.1; floorShape->collision_type = 0;  
      
    floorShape->data = floor;  
      
    cpSpaceAddStaticShape(space, floorShape);  
      
    floorShape = cpPolyShapeNew(floorBody, 4, verts5, cpv(-320.0f / 2, 81.0f / 2));  
      
    floorShape->e = 0.5; floorShape->u = 0.1; floorShape->collision_type = 0;  
      
    floorShape->data = floor;  
      
    cpSpaceAddStaticShape(space, floorShape);  
Este código debería ser facil de entender ahora. Crea 5 formas, todas adjuntadas al cuerpo del piso y después se setean algunas propiedades. Hay dos diferencias menores entre la forma en que la forma del piso es definida y las definicion anterior de la pelota. La primer diferencia es el ajuste de la fricción desde 0.8 a 0.1, sin esta fricción entre el piso y la pelota. La segunda diferencia es la manera en que las formas son agregadas, se utiliza cpSpaceAddStaticShape en vez de cpSpaceAddSpace para que la forma no se mueva. Chipmunk usa esto para optimizar los calculos en cada paso y reducir uso de CPU. Si ejecutamos el proyecto la pelota va a caer y en vez de pasar a través del piso va a golpear con el mismo y frenarse. Esto es un buen indicio de que las dos formas estan interactuando correctamente, no nos da la mejor demostración de lo que aprendimos. Busquemos el código donde creamos y configuaramos el cuerpo de la pelota y cambiemos la posición del vector X de 160 a 60.
ballBody->p = cpv(60, 250); 
si ejecutamos otra vez el demo vamos a ver que la pelota comienza a deslizarce un poco más a la izquierda cayendo con la inclinación y haciendo un movimiento muy realístico a través del piso.

viernes, 10 de agosto de 2012

ChipMunk - Librería de física 2D - Videojuegos para Iphone - Siguiendo el movimiento de la pelota (Parte 5)

Ahora no hay código que se pueda enlazar con la simulación de Chipmunk con la gráfica de manera que la pelota se mueva correctamente. Esto se realiza extendiendo el metódo tick y leyendo las nuevas posiciones desde Chipmunk desde donde actualizaremos las coordenadas de nuestras imagén. Este proceso se puede realizar de varias formas (por ej. se puede almacenar una lisa de items para chequar y/o actualizar) pero por suerte Chipmunk esta diseñado para hacer las cosas tan abstractas como sea posible. En la parte 4 creamos una forma, que esta enlazada con un cuerpo particular, también almacenamos una referencia a nuestra UIImageView en la misma forma. Esto significa que todos los datos que necesitamos estan centralizados, con esto en mente Chipmunk nos ofrece una función:
  
cpSpaceHashEach(cpSpaceHash * hash, cpSpaceHashIterator func, void * data)
Esta función toma un hash (un array), una función que será llamada para cada elemento en el array y opcionalmente para un parametro convencional. Entonces agregamos este código después de cpSpaceStep
 
    // Llama a nuestra funcion para cada forma 
      
    cpSpaceHashEach(space->activeShapes, &updateShape, nil);  

Como se explico antes, se llamara a la funcion updateShape (que implementaremos luego) para el array activeShapes. Discutiremos el termino formas (shapes) "activas" en más detalle cuando implementemos el piso, no se preocupen por los detalles ahora. Ahora necesitamos implementar la función updateShape empezando por agregar esto en el .h después de las otras declaraciones de los métodos.
    
void updateShape(void *ptr, void* unused);
   // Actualiza la representación visual (sprite)  
y luego, este código en el archivo de implementación
   
   
void updateShape(void *ptr, void* unused) {  
      
    // Obtenemos la forma  
      
    cpShape *shape = (cpShape*)ptr;  
      
    // Asegurate que todo está correcto  
      
    if(shape == nil || shape->body == nil || shape->data == nil) {  
      
    NSLog(@"Unexpected shape please debug here...");  
      
    return;  
      
    }  
      
    // Finalmente chequea si el objeto es un UIView de cualquier tipo 
      
    // y actualizamos la posición de acuerdo a ello  
      
    if([shape->data isKindOfClass:[UIView class]]) {  
      
    [(UIView *)shape->data setCenter:CGPointMake(shape->body->p.x, 480-shape->body->p.y)];  
      
    }  
      
    else  
      
    NSLog(@"The shape data wasn't updateable using this code.");  
      
    }  
Esta última parte del código hace varias cosas, sin embargo solo 1 o 2 lineas de código son requeridas. Agregué algunas advertencias para que vean cuales pueden llegar a ser los problemas, lo importante es donde realizamos el update de nuestra posición. Presten atención al hecho de que que no asigne directamente las coordenadas Y, esto es porque Chipmunk tiene un sistema de coordenadas diferentes al de Cocoa. El origen de las coordenadas en Cocoa esta en la esquina superior izquierda y en Chipmunk el origen esta en la esquina inferior izquierda entonces hay que tener especial cuidado en esto. Cocos2D comparte el mismo sistema de coordenas que Chipmunk.
Ahora que finalmente parece que tenemos todo lo que necesitamos para que se mueva la pelota es hora de que compilemos y corramos el proyecto. Si seguiste correctamente todas las instrucciones deberias ver la pelota cayendo y aumentando su velocidad descendente. Vemos que la pelota pasa a traves del piso, esto es lo que solucionaremos en las siguientes partes del tutorial.

jueves, 9 de agosto de 2012

ChipMunk - Librería de física 2D - Videojuegos para Iphone - Definiendo el cuerpo y la forma (Parte 4)

Definir el cuerpo es un proceso simple aunque requiere un poco de conocimiento de física. Chipmunk dispone de una función  cpBodyNew(masa, momento); que maneja todas las condiciones iniciales que  requiere un cuerpo. En general todo esto es para la 
posición del cuerpo.

Entonces el siguiente código definirá el cuerpo de nuestra pelota, establecerá la posición y la agregará a nuestro espacio. El siguiente código irá al final del método setupChipmunk.
  

    // Crea el cuerpo de la pelota con 100 de masa  
    // y el momento es infinito 
      
    cpBody *ballBody = cpBodyNew(100.0, INFINITY);  
      
    // Setear la posición inicial   
      
    ballBody->p = cpv(160, 250);  
      
    // Agregar el cuerpo al espacio  
      
    cpSpaceAddBody(space, ballBody);  

Luego debemos especificar como la pelota interactua con otros objetos definiendo su forma(shape) y asociandole propiedades.

Este proceso es actualmente el más complejo de todos y a veces requiere que se modifiquen algunas cosas mediante prueba y error. Chipmunk consta de 3 funciones para crear formas basadas en el tipo de forma que se desee.

- cpCircleShapeNew(cpBody * body, cpFloat radius, cpVect offset)
- cpSegmentShapeNew(cpBody * body, cpVect a, cpVect b, cpFloat radius)
- cpPolyShapeNew(cpBody * body, int numVerts, cpVect * verts, cpVect offset)

El significado de los argumentos en esas funciones es el siguientes:
body: el cuerpo asociada con la forma que estan creando
radius: el radio del circulo que estas creando o el ancho de la linea/segmento
offset: donde posicionar la forma relativa al centro del cuerpo
a, b : los puntos comienzo/final para el segmento (crea una linea entre dos puntos) numVerts, verts: para los poligonos se provee un array de los vertices que que definen la forma (debido a restricciones que tiene C se necesita pasar numVerts que es el numero de items/puntos en un array). Entonces ahora que tenemos un vistazo de como crear formas todo lo que falta es saber como definir sus propiedades, las explicaciones se encuentran en los comentarios del siguiente código.
  
    // Crear la forma asociada con el cuerpo de la pelota  
      
    cpShape *ballShape = cpCircleShapeNew(ballBody, 20.0, cpvzero);  
      
    ballShape->e = 0.5; // Elasticity  
      
    ballShape->u = 0.8; // Friction  
      
    ballShape->data = ball; // Associate with out ball's UIImageView  
      
    ballShape->collision_type = 1; // Collisions are grouped by types  
      
    // Agregar la forma al espacio  
      
    cpSpaceAddShape(space, ballShape);  
Se pueden definir más propiedades, se puede chequear la documentación si se quiere saber más sobre ellas, por ahora lo que necesitamos que esta configurado los datos y el collision_type. Se puede eliminar la elasticidad y la fricción e incluso cambiar sus valores.

jueves, 2 de agosto de 2012

ChipMunk - Librería de física 2D - Videojuegos para Iphone - Inicializando Chipmunk (Parte 3)


 Para comenzar a trabajar con Chipmunk se necesita:

 1) Inicializarlo
 2) Usar un timer para que Chipmunk pueda saber los pasos de la simulación
 3) Crear y Configurar el espacio

Inicializar Chipmunk es la parte más facil, se necesita llamar a cpInitChipmunk(); en alguna parte de la inicialización de tu aplicación. El timer puede ser seteado usando un simple objeto NSTimer o en algunos casos si estas usando algún game engine deberías usar el timer del engine (para asegurar la sincronización). Finalmente crear un espacio es tan simple como llamar a cpSpaceNew();

Para completar estos 3 pasos hay que comenzar agregando el #import correcto para el .h y .m de tu controlador.
#import "chipmunk.h" 
Luego en el .h se necesita agregar una variable para almacenar nuestro espacio y dos métodos, el .h completo debería verse de esta manera:
    
 
    #import "chipmunk.h"  
      
    @interface ChipmunkTutorialViewController : UIViewController {  
      
        UIImageView *floor; // imagen del piso  
      
        UIImageView *ball; //  imagen de la pelota  
      
        cpSpace *space; // Objeto espacio  
      
    }  
      
    - (void)setupChipmunk; 
      
    - (void)tick:(NSTimer *)timer; // Se dispara en cada "frame"  
      
    @end  
Ahora en el archivo de implementacón deberiamos agregar la siguiente llamada en el viewDidLoad
[self setupChipmunk];  
y finalmente la declaración de los dos métodos definidos
      
    - (void)setupChipmunk {  
      
        // Comienza chipmunk       
        cpInitChipmunk();  
      
        // Crea un objeto espacio       
        space = cpSpaceNew();  
      
        // Define el vector de gravedad       
        space->gravity = cpv(0, -100);  
      
        // Crea un timer que dispara en un intervalo constante (desired frame rate)    
        // Notar que si se esta usando demasiada CPU 
        // El timer debe ser disparado antes de que se complete el ultimo frame
        // Hay tecnicas que se pueden usar para evitar esto pero no se realizaran aqui 
      
        [NSTimer scheduledTimerWithTimeInterval:1.0f/60.0f target:self selector:@selector(tick:) userInfo:nil repeats:YES];  
      
    }  
      
    // LLama a cada frame
      
    - (void)tick:(NSTimer *)timer {  
      
        // Le dice a Chipmunk que avance otro "paso" en la simulación    
        cpSpaceStep(space, 1.0f/60.0f);  
      
    } 
Notarán que también definimos la gravedad para nuestro space. La gravedad es algo que comparten globalmente todos los objetos entonces es de sentido común setearlo al principio. Una cosa que quizás no se comprenda rapidamente es que el valor de la gravedad es una fuerza que se aplica verticalmente hacia abajo con una elasticidad de 100 pero los valores se pueden ajustar como quieran.
El código debe compilar y ejecutarse sin ningún problema pero todavía no se vera nada nuevo ya que no hemos definido nuestros cuerpos (bodies).

martes, 24 de julio de 2012

ChipMunk - Librería de física 2D - Videojuegos para Iphone - Conceptos básicos (Parte 2)

Ahora que tenemos configurado nuestro proyecto y esta listo para comenzar, podemos empezar a estudiar Chipmunk. Para eso necesitamos conocer la terminología básica de Chipmunk y saber como esta organizado.

Para simular un mundo con física necesitamos establecer ciertas reglas como por ej la gravedad para nuestro nuevo "Universo", también necesitamos crear un contenedor para todos nuestros objetos, en Chipmunk a esto se lo denomina espacio (space).
Para definir cualquier objeto es necesario establecer cual es su masa y otras propiedades del mismo. Esto se hace con lo que Chipmunk llama cuerpo (body).
Un cuerpo no produce colisiones por si mismo porque no tiene "forma" (shape) cuando interactua con otros objetos. Algunos objetos no son homogeneos, a veces se necesitan definir diferentes parametros para diferentes partes de un objeto (por ej un helado tiene dos partes, una más blanda que la otra).

Para definir que áreas de un cuerpo interactuan con el resto del mundo y las diferentes superficies, se necesitan agregar una o mas formas (shapes) a un body. En Chipmunk hay tres tipos de formas disponibles: circulo, segmento y polígono. Combinando estos tres tipos de formas se definen casi todos los tipos de área de interacción imaginables para nuestros cuerpos. Obviamente que las formas agregadas al mismo cuerpo no producen colisiones  entre ellos.
No siempre es mejor completar el cuerpo con formas para que se unan con los sprites, agregar muchas formas incrementa  el número de cálculos que Chipmunk necesita para cada frame, es mejor simplificar las fomas de manera que cubran las partes importantes.

Podemos cambiar cosas como la velocidad o la posición del cuerpo pero no es recomendado. El método principal para  hacer esto es, como en el mundo real, es aplicar fuerzas. Una fuerza es un vector. Para trabajar con vectores Chipmunk tiene una libreria llamada cpVect que permita hacer las operaciones más comunes como multiplicar y proyectar 2 vectores.
Chipmunk también soporta Joints que nos permiten conectar 2 cuerpos mediante diferentes puntos.

martes, 12 de junio de 2012

ChipMunk - Librería de física 2D - Videojuegos para Iphone - Introducción (Parte 1)

ChipMunk es una librería para física 2D muy facil, rápida e independiente del engine gráfico que utilizas para tus juegos. En este caso vamos a utilizar Cocos2D.
En este artículo veremos las características básicas de esta librería para que después puedas continuar por tu cuenta.
LLegaremos a hacer la simulación que se muestra en la figura:

Setup:
Antes de comenzar debemos configurar el proyecto para luego enfocarnos en ChipMunk.
Creamos un proyecto de XCode seleccionando el template "View-Based-Application" o "Single View Application" para versiones posteriores de XCode.
Luego debemos importar todos los archivos de ChipMunk necesarios, para eso descargamos el código de ChipMunk desde aquí , al descomprimirlo vamos a encontrarnos con documentos, demos, etc pero lo que vamos a necesitar esta en la carpeta "src" aunque en nuevas versiones de chipmunk los archivos necesarios los encontré en la carpeta "include".
Antes de importar todos los archivos, sugeriría que creen un nuevo grupo en el proyecto al que llamaremos "Other Sources" y luego hacer "Add Existing Files ..." y seleccionar los archivos que se encuentran en la carpeta src. Tenemos que asegurarnos de seleccionar "Copy items into destination group´s folder (if needed)"  . El proyecto debería quedar como muestra la imagen siguiente:


Ahora debemos agregar al proyecto las dos imágenes:



y en el header del View Controller agregar el siguiente código:

UIImageView *floor; // imagen del piso
UIImageView *ball; //  imagen de la pelota
En el método viewDidLoad que se encuentra en el archivo de implementación agregamos el siguiente código:
floor = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"floor.png"]];

floor.center = CGPointMake(160, 350);

ball = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"ball.png"]];

ball.center = CGPointMake(160, 230);

[self.view addSubview:floor];

[self.view addSubview:ball];
Fuente: http://www.alexandre-gomes.com/articles/chipmunk/

Compartir en twitter y en facebook

Una de las opciones es utilizar el framework ShareKit: http://www.getsharekit.com que además de permitirnos compartir en twitter nos va a permitir hacerlo en otras redes sociales como facebook, google reader, delicious, etc.
Compartir un item consite en dos pasos:

1.Crear un SHKItem con el texto que se quiere postear.
2.Llamar al método shareItem: de la subclase apropiada


- (IBAction)tweet:(id)sender
{
    SHKItem *aTweet = [SHKItem text: @"Share this text"];
    [SHKTwitter shareItem:aTweet];
}

- (IBAction)facebook:(id)sender
{
    SHKItem *post = [SHKItem text: @"Share this text"];
    [SHKFacebook shareItem:post];
}

Otras opciones para twitter son

RSOAuthEngine OAuth engine basado en ARC
MGTwitterEngine
MPOAuth


Para compartir en facebook  podemos utilizar el sdk de ellos que lo podemos descargar desde aquí
https://github.com/facebook/facebook-ios-sdk
Tienen también un buen tutorial:
https://developers.facebook.com/docs/mobile/ios/build/

lunes, 11 de junio de 2012

UIView

Cada subclase de UIView tiene un método drawRect:. El código para dibujar un view se encuentra en este método. Cada vez que se dibuja una instancia de UIView el sistema prepara un contexto para esa view.
El contexto es de tipo  CGContextRef (Core Graphics Context Reference) y es responsable de producir la imagen y de recibir los comandos para poder dibujar. Un contexto gráfico también tiene información del color que se esta utilizando para dibujar, del sistema de coordenadas y del ancho de las lineas que se están dibujando.
drawRect recibe como parámetro una estructura CGRect que es el rectángulo que se va a dibujar. CGRect tiene origen y tamaño que también son estructuras. Origen es un CGPoint que tiene dos miembros x e y. CGSize tiene también dos miembros width y height. La imagen siguiente nos muestra un CGRect.


Hay dos formas de instanciar un UIView una es mediante alloc e initWithFrame y otra es crearlo a través del Interface Builder.


jueves, 12 de abril de 2012

Evitar que métodos que consumen mucho tiempo se ejecuten en el hilo principal

Si tenemos un método que pide y trae algo de la web, por ejemplo una imagen, sabemos que va a tardar mucho tiempo (unos segundos). Lo que conviene es crear una queue (una cola) para que esto corra en un hilo separado y no en el hilo principal que es donde se esta ejecutando la interfaz del usuario (UIKit queue).
Para esto usamos la API GCD (Grand Central Dispatch).
Este es un ejemplo de como hacerlo:

Este es el método sin crear una queue 

-(void) viewWillAppear:(BOOL)animated
{
    NSData  *imageData = [NSData dataWithContentsOfURL:networkURL]; 
    UIImage *image = [UIImage imageWithData:imageData];
    self.imageView.image = image;
    self.imageView.frame = CGRectMake(0, 0, image.size.width, image.size.heigh);
    self.scrollView.contentSize = image.size;
} 

Este es el método con la queue 

-(void) viewWillAppear:(BOOL)animated
{
    // Creo la queue
    dispatch_queue_t downloadQueue = dispatch_queue_create("image downloader", NULL);
    dispatch_async(downloadQueue, ^{
        
        NSData  *imageData = [NSData dataWithContentsOfURL:networkURL]; 
        
        //Llamadas al UIKit en el queue principal
        dispatch_async(dispatch_get_main_queue(), ^{
            UIImage *image = [UIImage imageWithData:imageData];
            self.imageView.image = image;
            self.imageView.frame = CGRectMake(0, 0, image.size.width, image.size.heigh);
            self.scrollView.contentSize = image.size;

        });
    });

    // Cuando no existan más bloques release
    dispatch_release(downloadQueue);
} 

lunes, 26 de marzo de 2012

Cambiar nombre de la aplicación

Para cambiar el nombre de la aplicación  hay que seleccionar el proyecto luego hacer doble click en Target y cambiamos el nombre. Luego en la pestaña Build Settings bajo el header Packaging cambiamos el nombre donde dice Product name, vamos al menú Product > Clean y luego Build.

jueves, 8 de marzo de 2012

Método para calcular los días, horas, minutos y segundos que faltan entre la fecha actual y otra futura


- (void) tiempoHasta:(NSString *) hasta {
    
    // Fecha actual
    NSDate *date = [NSDate date];
    int secondsNow =(int)[date timeIntervalSince1970];
   
    // Convierto el string hasta 
    NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
    [dateFormat setDateFormat:@"yyyyMMdd"];
    NSDate *hastaDate = [dateFormat dateFromString:hasta]; 
    
    int secondsTarget=(int)[hastaDate timeIntervalSince1970];
    int differenceSeconds=secondsTarget-secondsNow;
    int days=(int)((double)differenceSeconds/(3600.0*24.00));
    int diffDay=differenceSeconds-(days*3600*24);
    int hours=(int)((double)diffDay/3600.00);
    int diffMin=diffDay-(hours*3600);
    int minutes=(int)(diffMin/60.0);
    int seconds=diffMin-(minutes*60);
}

jueves, 23 de febrero de 2012

Iconos para nuestra App

Conviene que el icono de nuestra aplicación lo hagamos de 512 x 512 pixels porque cuando subamos la aplicación a la AppleStore nos va a pedir una imagen de ese tamaño.
Además deberíamos crear imágenes con los siguientes tamaños para los distintos dispositivos:

Iphone: 57 x 57 pixels 
High Resolution Iphone/Ipod: 114 x114 pixels
Ipad: 72 x 72 pixels
High Resolution Ipad: 144 x 144 pixels

miércoles, 8 de febrero de 2012

Crear un botón por código

// Creo el boton y lo inicio con un frame que creo con la funcion CGRectMake.
UIButton *reservaButton = [[UIButton alloc] initWithFrame:CGRectMake(230, 45, 76, 25)];

// El boton tiene una imagen, la agrego como background
[reservaButton setBackgroundImage:[[UIImage imageNamed:@"reservar.png"] 
 stretchableImageWithLeftCapWidth:75.0 topCapHeight:0.0] 
                         forState:UIControlStateNormal];

// Enlazo el boton con el método reserve
[reservaButton addTarget:self 
                  action:@selector(reserve:)   
        forControlEvents:UIControlEventTouchUpInside];


martes, 31 de enero de 2012

Agregar pin a un mapa

Lo conveniente es crear una nueva clase que llamaremos Pin:
Pin.h

#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
#import <CoreLocation/CoreLocation.h>

@interface Pin : NSObject{ 
    CLLocationCoordinate2D coordinate;        
    NSString *subtitle;        
    NSString *title;     
}
    
@property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
@property (nonatomic,retain)NSString *subtitle;
@property (nonatomic,retain) NSString *title;
- (id) initWithCoords:(CLLocationCoordinate2D) coords;

@end 

Pin.m
#import "Pin.h"
@implementation Pin
@synthesize coordinate;
@synthesize subtitle;
@synthesize title;

- (id) initWithCoords:(CLLocationCoordinate2D) coords{

    self = [super init];
    
    if (self != nil)
        coordinate = coords;
    
    return self;
}

- (void) dealloc{
    [title release];
    [subtitle release];
    [super dealloc];

}
@end


Luego agregamos al mapa el pin:
CLLocationCoordinate2D pinlocation;
pinlocation.latitude = latitude;
pinlocation.longitude  = longitude;
Pin *pin = [[Pin alloc] initWithCoords:pinlocation];
pin.title = self.tituloSel;
[mapa removeAnnotations:[mapa annotations]];
[mapa addAnnotation:pin];
[pin release];

miércoles, 18 de enero de 2012

Mostrar otra pantalla

self.infoController = [[InformationViewController alloc]
                      initWithNibName:@"InformationViewController" 
                               bundle:[NSBundle mainBundle]];
 
[self presentModalViewController:infoController animated:YES];


y para volver desde esa nueva pantalla

  [self dismissModalViewControllerAnimated:YES];

Otra forma de pasar a otra pantalla
  progressView = [[ProgressViewController alloc] initWithNibName:@"ProgressViewController" bundle:nil];
        [self.view addSubview:progressView.view];