Professional Documents
Culture Documents
Hardware
Software
Conocimiento
Ideas
Tiempo
HARDWARE NECESARIO
Mnimo
Recomendado
SOFTWARE NECESARIO
Mnimo
SDK PIXELMATOR SMULTRON
Recomendado
SDK PHOTOSHOP DREAMWEAVER SMARTSVN NAVICAT
1.Introduccin
- Vamos a crear una aplicacin de ejemplo y repasaremos algunos aspectos bsicos - Daremos un repaso a Objective - C - Gestin de memoria con ARC - Delegation and Core Location
El modelo-vista-controlador es un patrn arquitectnico. Se emplea para estructurar las interfaces de los programas de una manera en la que separamos tareas diferentes en diferentes capas. Por un lado tenemos la presentacin, por otro la lgica de aplicacin y por otro la informacin del dominio.
El mecanismo de delegados consiste en que un clase A implementa los mtodos de otra clase B para hacer se cargo del comportamiento de esta, cuando esos mtodos son llamados. El objeto A se llama delegado de B
3.Aplicacin de ejemplo
- Ver diferentes templates de proyectos XCode - Iconos - Imgenes de Lanzamiento - Cmo creamos las interfaces desde Interface Builder - Declaracin de variables - Declaracin de mtodos - Creando conexiones de variables y objetos de IB - Enlazando objetivos y acciones - Ejecucin en el simulador - Ejecucin en el dispositivo - Debugger - Instruments
4.Gestin de vistas
- Las diferentes vistas se gestionan como diferentes capas, pudiendo superponer unas a otras y soportando transparencias.
5.Ciclo de vida
Delegate
Inicio Inicio {AbrirTitulo()} AbrirTitulo()
Controlador
Vista
Botn {Preferencias()}
AbrirPreferencias()
Preferencias()
Fin
6.Objective-C
- Objective-C es una extensin del lenguaje C - Las aplicaciones iOS se desarrollan utilizando Objective-C y las libreras de Cocoa Touch - Cocoa Touch est escrito en Objective-C y es un conjunto de APIs que nos permiten programar las aplicaciones
6.Clases
Coche int numRuedas; //Atributo -(int) getNumRuedas; //Mtodo -(void) setNumRuedas:(int)n;
- Clase: Dene una estructura y comportamiento. - Objeto: Es una instancia a una clase. - Atributo: Propiedad de una clase. - Mtodo: Dene un comportamiento - Evento: Interaccin del usuario con la mquina. - Mensaje: comunicacin dirigida a un objeto ordenndole que ejecute uno de sus mtodos.
7.Instancias
Para crear una instancia de una clase primero debemos pedir memoria
NSMutableArray *listaPersonas = [NSMutableArray alloc];
Pero para ser usado ese objeto, necesita ser inicializado, para ello llamaremos a su mtodo constructor.
[listaPersonas init];
8.Mensajes
- Mensaje : Comunicacin dirigida a un objeto para que ejecute uno de sus mtodos
NSMutableArray *listaPersonas = [[NSMutableArray alloc] init]; [listaPersonas addObject:@""];
9.Listas y bucles
- Usamos NSArray para crear listas de objetos. NSArray tiene un tamao jo, como una constante, denida cuando se crea - NSMutableArray es como NSArray pero la gestin de memoria es dinmica, podemos aadir y quitar elementos y el compilador gestionar el tamao en memoria de la lista
NSMutableArray [listaPersonas [listaPersonas [listaPersonas *listaPersonas = [[NSMutableArray alloc] init]; addObject:@"Carlos"]; addObject:@"David"]; addObject:@"Juan"];
10.NSString
- NSString es una clase de Objective-C usada para representar cadenas.
NSString *cadena1 = @"Reserva de memoria implcita"; NSString *cadena2 = [[NSString alloc] initWithString:@"Reserva de memoria con reference counting"]; [cadena2 release]; NSString *cadena3 = [[[NSString alloc] initWithString:@"Reserva de memoria autorelease"] autorelease];
14.Gestin de memoria
Implcito NSString *cadena = [NSString stringWithString:@Hola]; //sin alloc Manual alloc +1 retain +1 release -1 NSString *cadena = [[NSString alloc] initWithString:@Hola]; [cadena release]; Automtico NSString *cadena = [[NSString alloc] initWithString:@Hola]; [cadena autorelease];
- Esto no signica que el contador de referencias desaparezca, sino que es automtico. - Cuando el precompilador considera que el objeto no se va a usar ms, aade automticamente una lnea para liberar ese objeto:
[obj release];
16.Referencias fuertes
Se utiliza el atributo strong. Especica que hay una relacin de propiedad (fuerte) sobre el objeto de destino. Sin ARC: @property(retain) NSObject *obj; Con ARC: @property(strong) NSObject *obj; @property(weak) NSObject *obj;
17.Referencias dbiles
Se utiliza el atributo weak. Especica que hay una relacin de no-propiedad (dbil) sobre el objeto de destino. Contamos con la ventaja de que si el objeto en cuestin resulta desalojado de la memoria (dealloc), entonces el valor de la propiedad se ajustar automticamente a nil y, por tanto, en ningn caso se producir un cuelgue del programa dado que el lenguaje permite enviar mensajes a nil.
Repaso 2
1.Introduccin
- Cadenas - Propiedades comunes de los objetos - Labels - Imgenes - Slider - AlertView - MapKit - Text Input - UIView - UIScrollView - UIWebView - Mltiples controladores - AppDelegate
2.Cadenas
Componemos la cadena con el texto de los labels y textelds
! ! ! ! ! NSString cadena = cadena = cadena = cadena = *cadena [cadena [cadena [cadena [cadena = [[NSString alloc] initWithString:@"La cadena es : "]; stringByAppendingFormat:label1.text]; stringByAppendingFormat:textField1.text];! stringByAppendingFormat:label2.text]; stringByAppendingFormat:textField2.text];! !
Posicin: [objeto setCenter:CGPointMake(30,30)]; Tamao: [objeto setBounds:CGRectMake(0,0,300,300)]; Transparencia: [objeto setAlpha:0.5]; Hidden: [objeto setHidden:TRUE]; ...
4.Label
Cambiar texto de un UILabel: [label setText:@Texto deseado];
5.Imgenes
Instanciar UIImageView y aadirlo a la vista
UIImageView *imagen = [[UIImageView alloc] initWithFrame:CGRectMake(0,0,100,100)]; [imagen addSubview:self.view];
6.Slider
Conguracin del slider en la carga de la vista
- (void)viewDidLoad { [slider setMinimumValue:1.0]; ! [slider setMaximumValue:10.0]; ! [slider setValue:5.0]; [super viewDidLoad]; }
7.UISegmentedControl
Detectar cambio en un UISegmentedControl.
- (IBAction)segmentAction:(id)sender { ! switch ([sender selectedSegmentIndex]) ! { ! ! case 0: //Hacer algo para la primera pestaa ! ! ! break; ! ! case 1: //Hacer algo para la primera pestaa ! ! ! break; ! } }
8.AlertView
Mostramos un AlertView
UIAlertView *alert = [[UIAlertView alloc] ! ! ! initWithTitle: @"Titulo" ! ! ! message: @"Texto aqu" ! ! ! delegate: nil ! ! ! cancelButtonTitle:@"OK" ! ! ! otherButtonTitles:nil]; [alert show]; [alert release];
9.MapKit
Debemos aadir los frameworks de MapKit Conguracin del mapa en la carga de la vista
{ ! ! ! ! ! ! } (void)viewDidLoad [mapa [mapa [mapa [mapa setMapType:MKMapTypeHybrid]; setZoomEnabled:YES]; setScrollEnabled:YES]; setShowsUserLocation:YES];!
[super viewDidLoad];
10.Text Input
- Cajas de introducir texto, permiten seleccionar diferentes tipos de teclados - Para liberar teclado implementar el protocolo UITextFieldDelegate y sobreescribir el mtodo de su delegado
- (BOOL)textFieldShouldReturn:(UITextField *)tf { [tf resignFirstResponder]; return YES; }
11.UIView
- Uno de los elementos ms usados - Podemos tener vistas dentro de otras vistas de manera jerrquica - Podemos sobreescribir el mtodo drawRect para que la vista pinte algo especco
12.UIScrollView
- Crearemos una app de tipo Single View Application - Crear un UIScrollView programticamente y aadirlo a la vista - Implementar UIScrollViewDelegate en nuestro controlador - Crear un UIImageView y asignarle una imagen, aadirlo al UIScrollView - Sobreescribir los mtodos adecuados para que nos permita hacer zoom sobre la imagen
12.UIScrollView
- Creacin y ajuste de elementos
//Instanciar ScrollView sv = [[UIScrollView alloc] initWithFrame: CGRectMake(0,0,self.view.bounds.size.width, self.view.bounds.size.height)]; [self.view addSubview:sv]; [sv release]; //Instanciar UIImageView iv = [[UIImageView alloc] initWithFrame: CGRectMake(0,0,self.view.bounds.size.width*2, self.view.bounds.size.height*2)]; [sv addSubview:iv]; [iv release]; //Asignar propiedades UIImageView [iv setImage:[UIImage imageNamed:@"wallpaper.jpg"]]; //Asignar propiedades UIScrollView [sv setContentSize:CGSizeMake(iv.bounds.size.width, iv.bounds.size.height)]; [sv setMinimumZoomScale:0.5]; [sv setMaximumZoomScale:2.5]; [sv setZoomScale:1.0 animated:TRUE]; [sv setDelegate:self];
12.UIScrollView
- Devolver vista sobre la que se realizar zoom
-(UIView*)viewForZoomingInScrollView:(UIScrollView *)scrollView{ return iv; }
13.UIWebView
Cargar web en un UIWebView
-(IBAction)irAPagina:(id)sender { ! //Obtain the url ! NSString *urlAddress = textField.text; ! ! //Create an NSURL Object ! NSURL *url = [NSURL URLWithString:urlAddress]; ! ! //URL Request Object ! NSURLRequest *requestObj = [NSURLRequest requestWithURL:url]; ! ! //Load the request in the UIWebView. ! [webView loadRequest:requestObj]; }
14.UITabBar
Seleccionar tabButton
//Seleccionar el primer elemento [tabBar setSelectedItem:[tabBar.items objectAtIndex:0]];
Recoger pulsacin
- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item { ! switch (item.tag) { ! ! case 0: ! ! ! //Pestaa1 ! ! ! break; ! ! case 1: ! ! ! //Pestaa2 ! ! ! break; ! }! ! ! }
15.Mltiples controladores
16.AppDelegate
- Para controlar el ciclo de vida utilizaremos el AppDelegate. - En AppDelegate instanciaremos nuevos controladores y eliminaremos los que no usemos. - Desde los controladores podremos acceder al AppDelegate para invocar un mtodo
#import ClaseD.h ClaseD *mainDelegate = (ClaseD*) [[UIApplication sharedApplication] delegate]; [mainDelegate cambiarAVista2];
Repaso 3
1.Introduccin
- UITableView y UITableViewController - Edicin de UITableView - UINavigationController - UIPopoverController - Vistas Modales
2.UITableView
- Podemos trabajar con este elemento haciendo subclassing de UITableViewController o implementando el delegate de UITableViewControllerDelegate en otro controlador - Vamos a crear un Single View Application - Mostrar una lista de los meses en un UITableView
2.UITableView
- Implementar el protocolo UITableViewDelegate en nuestro controlador - Escribir los mtodos del delegate - Rellenar array
lista = [[NSMutableArray alloc] initWithCapacity:12]; [lista addObject:@"Enero"]; [lista addObject:@"Febrero"]; [lista addObject:@"Marzo"]; [lista addObject:@"Abril"]; [lista addObject:@"Mayo"]; [lista addObject:@"Junio"]; [lista addObject:@"Julio"]; [lista addObject:@"Agosto"]; [lista addObject:@"Septiembre"]; [lista addObject:@"Octubre"]; [lista addObject:@"Noviembre"]; [lista addObject:@"Diciembre"];
2.UITableView
- Mtodos para rellenar contenido
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return [lista count]; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"UITableViewCell"]; if (!cell) { cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"UITableViewCell"] autorelease]; } [[cell textLabel] setText:[lista objectAtIndex:indexPath.row]]; return cell; }
2.UITableView
- Mtodo para modo de editar
- (IBAction)toggleEditingMode:(id)sender { if ([tableView isEditing]) { [sender setTitle:@"Editar"]; [tableView setEditing:NO animated:YES]; } else { [sender setTitle:@"Hecho"]; [tableView setEditing:YES animated:YES]; } }
2.UITableView
- Mtodo para mover celdas
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath { if (fromIndexPath.row == toIndexPath.row) { return; } //Quitamos elemento de posicin from NSString *e1 = [lista objectAtIndex:fromIndexPath.row]; [e1 retain]; [lista removeObjectAtIndex:fromIndexPath.row]; //Lo aadimos a posicin to [lista insertObject:e1 atIndex:toIndexPath.row]; [e1 release]; }
2.UITableView
- Mtodo para eliminar celdas
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { if (editingStyle == UITableViewCellEditingStyleDelete) { //Eliminamos el elemento del array [lista removeObjectAtIndex:indexPath.row]; //Y del tableView con una animacin [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:YES]; } }
2.UITableView
- Mtodo para cuando seleccionemos una celda
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { NSLog(@"Ha seleccionado el mes %@",[lista objectAtIndex:indexPath.row]); }
3.UINavigationController
- Cambiemos algo de cdigo en AppDelegate para aadir un UINavigationController
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease]; // Override point for customization after application launch. UIViewController *vc = [[[ViewController alloc] initWithNibName:@"ViewController" bundle:nil] autorelease]; self.window.rootViewController = [[[UINavigationController alloc] initWithRootViewController:vc] autorelease]; [self.window makeKeyAndVisible]; return YES; }
3.UINavigationController
- Congurar barra de navegacin
//Poner ttulo [self.navigationItem setTitle:@"Meses"]; //Aadir botn editar UIBarButtonItem *editar = [[UIBarButtonItem alloc] initWithTitle:@"Editar" style:UIBarButtonItemStylePlain target:self action:@selector(toggleEditingMode:)]; self.navigationItem.rightBarButtonItem = editar; [editar release];
4.UIPopoverController
- Vamos a hacer un nuevo ejemplo p a r a i Pa d y u s a r e m o s u n UIPopoverController, que slo est disponible en estos dispositivos y no en iPhone e iPod Touch - Crear proyecto Single View Application - Aadir otro controlador y programarlo con la vista que queramos mostrar
4.UIPopoverController
1. Implementar protocolo UIPopoverControllerDelegate 2. Crear puntero en la cabecera de nuestro controlador
UIPopoverController *mesesPopover;
4.UIPopoverController
- Mtodo del delegate
- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController { [popOver autorelease]; popOver = nil; }
4.UIPopoverController
- Mtodo que lo despliega
-(IBAction)verPopover:(id)sender{ if (popOver==nil) { Otro *otro = [[[Otro alloc] initWithNibName:@"Otro" bundle:nil] autorelease]; popOver = [[UIPopoverController alloc] initWithContentViewController:otro]; [popOver setDelegate:self]; [popOver presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES]; } else { [popOver dismissPopoverAnimated:YES]; [popOver autorelease]; popOver = nil; } }
5.Vistas Modales
- Las vistas modales son ViewControllers predenidos que nos proporciona el sistema y que nos permiten hacer cosas habituales como seleccionar una foto, enviar un mail, elegir un contacto, etc..
5.Vistas Modales
- En nuestro ejemplo vamos a aadir un botn nuevo que nos permita enviar un mail 1. Implementar el protocolo
MFMailComposeViewControllerDelegate
2. Aadir el framework
MessageUI.framework #import <MessageUI/MessageUI.h> #import <MessageUI/MFMailComposeViewController.h>
5.Vistas Modales
- Sobreescribir mtodo del delegate implementado
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error {! ! [self dismissModalViewControllerAnimated:YES]; }
5.Vistas Modales
- Invocar vista modal
! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! Class mailClass = (NSClassFromString(@"MFMailComposeViewController")); if (mailClass != nil)!{ ! if ([mailClass canSendMail]) { ! ! MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init]; ! ! picker.mailComposeDelegate = self; ! ! picker.navigationBar.barStyle = UIBarStyleBlack; ! ! ! ! [picker setSubject:@"Ttulo del mensaje"]; ! ! ! ! // Aadir destinatarios por defecto ! ! NSArray *toRecipients = [NSArray arrayWithObject:@"correo@enviar.com"]; ! ! ! ! [picker setToRecipients:toRecipients]; ! ! ! ! // Rellenar contenido del mail por defecto ! ! NSString *emailBody = @"Introduce aqu tu texto..."; ! ! [picker setMessageBody:emailBody isHTML:NO]; ! ! ! ! [self presentModalViewController:picker animated:YES]; ! ! [picker release];! ! ! } }
Repaso 4
1.Introduccin
- Notication and Rotation - Camera - Settings - Localization - Multitarea - Gestures - Animaciones - Transiciones predenidas entre vistas
Texto
- Mtodo manejador
- (void)orientationChanged:(NSNotification *)note { NSLog(@"orientationChanged: %d", [[note object] orientation]); }
3.Camera
- Crearemos un programa que tome una foto de la biblioteca y la asigne en un UIImageView sobre la pantalla
3.Camera
- Implementar el protocolo UIImagePickerControllerDelegate - Obtener foto
-(IBAction)tomarFoto:(id)sender{ //Instanciar controlador UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init]; if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) { [imagePicker setSourceType:UIImagePickerControllerSourceTypeCamera]; } else { [imagePicker setSourceType:UIImagePickerControllerSourceTypePhotoLibrary]; } //Asignar la vista actual como delegate y presentarlo [imagePicker setDelegate:self]; [self presentModalViewController:imagePicker animated:YES]; [imagePicker release]; }
3.Camera
- Obtener foto seleccionada
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { //Obtener la imagen y asignarla a un UIImageView UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage]; [imagen setImage:image]; [self dismissModalViewControllerAnimated:YES]; }
4.Settings
- Guardar preferencias
NSUserDefaults *standardUserDefaults = [NSUserDefaults standardUserDefaults]; standardUserDefaults setObject:@Hola forKey:@"clave"]; [standardUserDefaults synchronize]; !
- Cargar preferencias
NSUserDefaults *standardUserDefaults = [NSUserDefaults standardUserDefaults]; NSString *cadena = [[standardUserDefaults objectForKey:@clave] retain];
5.Localization - XIBs
- Creamos nuevo proyecto Single View Application - Aadimos algunos labels y otros elementos a la vista - Despus aadimos a la localizacin de la vista el idioma Espaol - Desde la consola usaremos el comando ibtool para generar el chero de cadenas a partir de nuestro xib
ibtool --generate-strings-file ~/Desktop/ViewController.strings ViewController.xib
5.Localization - XIBs
- Editamos el chero para asignar los valores del idioma al que vamos a traducir
/* Class = "IBUILabel"; text = "Texto del label"; ObjectID = "8"; */ "8.text" = "Label text"; /* Class = "IBUINavigationItem"; title = "Titulo de la vista"; ObjectID = "10"; */ "10.title" = "Title of the view";
- Ahora usamos ibtool para crear un nuevo Xib basado en nuestro xib anterior
ibtool --strings-file ~/Desktop/ViewController.strings --write ../es.lproj/ViewController.xib ViewController.xib
- Esto nos modica el XIB cuando ese idioma sea el de por defecto utilizando los valores del chero de texto
5.Localization - Cdigo
- Para localizar el cdigo de la aplicacin utilizaremos la macro NSLocalizedString - Vamos a crear un label dinmicamente y queremos que est localizado
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0,0,100,20)]; [self.view addSubview:label]; [label setText: NSLocalizedString(@"Label aadida",@"El texto de la label que aadimos") ];
5.Localization - Cdigo
- Ese comando nos genera el chero Localizable.strings que contiene lo siguiente
/* El texto de la label que aadimos */ "Label aadida" = "Label aadida";
- Lo modicamos
/* El texto de la label que aadimos */ "Label aadida" = "Label added";
- Aadimos el chero Localizable.strings a nuestro proyecto - Si ejecutamos la app en el idioma al que hemos traducido, saldr localizada, ya que NSLocalizedString lee el chero Localizable.strings
6.Multitarea
- Controlamos la multitarea mediante la implementacin de ciertos mtodos en el AppDelegate de nuestras aplicaciones
7.Gestures
- Podemos denir ciertos comportamiento para los gestos que registra una vista mediante Gesture Recognizers
UITapGestureRecognizer - Toque UIPinchGestureRecognizer - Zoom UIRotationGestureRecognizer - Rotar UISwipeGestureRecognizer - Arrastrar izquierda o derecha UIPanGestureRecognizer - Mover UILongPressGestureRecognizer - Pulsacin larga
7.Gestures
- La forma de trabajar con gestures es la siguiente: 1. Implementar protocolo UIGestureRecognizerDelegate 2. Crear el gesture regognizer y aadirlo a la vista
UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeRightAction:)]; swipeRight.direction = UISwipeGestureRecognizerDirectionRight; swipeRight.delegate = self; [self.view addGestureRecognizer:swipeRight];! [swipeRight release];
3. Crear mtodo que se encarga de recoger el evento cuanto se produce ese gesto sobre la vista
-(void)swipeRightAction:(UIPanGestureRecognizer*)gestureRecognizer{ //METER CDIGO }
8.Animaciones
- Crear una interpolacin en el valor de las propiedades de un objeto
//DEFINIR PROPIEDADES INICIALES imagen.alpha=1; [UIView beginAnimations:nil context:NULL]; [UIView setAnimationDuration:0.5]; [UIView setAnimationDelegate:self]; !//DEFINIR PROPIEDADES FINALES !imagen.alpha=0; [UIView commitAnimations];
[UIView commitAnimations];
1.Touch Events
- Elementos como UIScrollView permiten hacer eventos multitctiles pero su comportamiento est predenido. - Usaremos Touch Events cuando queramos un comportamiento especco. - En este apartado crearemos una vista sobre la que poder pintar usando las caractersticas multitouch de los dispositivos. - Utilizaremos el gesto doble-tap para limpiar la pantalla
1.Touch Events
- Heredando de UIResponder podremos sobreescribir cuatro mtodos para capturar los distintos eventos: Uno o varios dedos tocan la pantalla:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
El sistema interrumpe este movimiento antes de que termine por una llamada u otro evento:
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;
- Podemos tocar y arrastrar sobre la pantalla y arrastrar para dibujar una linea - Con doble-tap limpiamos la pantalla
Line.m
#import Line.h @implementation Line @synthesize begin,end; @end
UIResponder no maneja el evento porque al no estar sobrescritos sus mtodos entonces enva el evento al siguiente respondedor. Mandar mensaje explcitamente al siguiente respondedor:
[[self nextResponder] touchesBegan:touches withEvent:event];
7.Circles
- Podemos tocar y arrastrar sobre la pantalla y arrastrar para dibujar una crculo - Con doble-tap limpiamos la pantalla
7.Circles
//Establecer contexto CGContextRef context = UIGraphicsGetCurrentContext(); //Poner Color [[UIColor blackColor] set]; //Calcular cuadrado que lo engloba CGPoint vector = CGPointMake(circle.end.x-circle.begin.x, circle.end.y-circle.begin.y); float radio = sqrt(pow(vector.x,2) + pow(vector.y,2)); float diametro = radio*2; float origenX = circle.begin.x - radio; float origenY = circle.begin.y - radio; CGRect bordes = CGRectMake(origenX,origenY,diametro,diametro); //Pintar Crculo CGContextFillEllipseInRect(context,bordes);
8.UIControl
- UIControl es la superclase de muchos elementos de Cocoa Touch, entre ellos UIButton o UISlider. - UIControl sobreescribe los mismos mtodos de UIResponder que hemos visto en este apartado - UIControl asocia cada posible evento con una constante. Por ejemplo UIControlEventTouchUpInside.
8.UIControl
- Veamos como UIControl manejara el evento UIControlEventTouchUpInside
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { // Referencia al toque que acaba de terminar UITouch *touch = [touches anyObject]; //Posicin del punto en el sistema de coordenadas del control CGPoint touchLocation = [touch locationInView:self]; // Esta el punto dentro de los mrgenes de mi vista? if (CGRectContainsPoint([self bounds], touchLocation)) { //Enviar mensaje a todos los targets registrados para este evento [self sendActionsForControlEvents:UIControlEventTouchUpInside]; } else { //Enviar un mensaje diferente [self sendActionsForControlEvents:UIControlEventTouchUpOutside]; } }
0.Introduction
- Las animaciones son la marca caracterstica de las interfaces de iOS y Mac OS X - Cuando queramos usar Core Animation debemos aadir el framework de QuartzCore - Hay dos clases con las que Core Animation funciona, estas son CALayer y CAAnimation - CALayer es un buffer que contiene una imagen, se pinta en pantalla mediante hardware, por lo que su funcionamiento es muy rpido. - CAAnimation causa un cambio mediante interpolacin en alguna propiedad de un objeto a lo largo de un periodo de tiempo. - En este apartado nos centraremos en CALayer
2.Creating a CALayer
2.Creating a CALayer
- Crear proyecto de tipo Single View Application - Aadir el framework QuartzCore - Incluir la librera <QuartzCore/QuartCore.h> donde vayamos a usar este framework - Aadir imagen a la vista ViewController.xib - Crear el puntero a la CALayer en ViewController.m - Instanciar nuestra CALayer en el mtodo ViewDidLoad de ViewController.m
2.Creating a CALayer
- Instanciaremos la CALayer en el mtodo ViewDidLoad de ViewController.m ViewController.m
//Crear el nuevo objeto de tipo CALayer boxLayer = [[CALayer alloc] init]; //Ajustar el tamao adecuado [boxLayer setBounds:CGRectMake(0,0,85,85)]; //Ajustar la posicin [boxLayer setPosition:CGPointMake(160,100)]; //Crear un UIColor, despus convertirlo a CGColorRef y asociarlo al color de fondo UIColor *rojo = [UIColor colorWithRed:1 green:0 blue:0 alpha:0.5]; CGColorRef rojoCG = [rojo CGColor]; [boxLayer setBackgroundColor:rojoCG]; //Hacer que la CALayer se sublayer de la layer de la vista del controlador [[self.view layer] addSublayer:boxLayer];
3.Layer Content
- Una layer es simplemente una imagen - Su contenido puede ser generado a partir de una imagen o programticamente
//Crear imagen, y obtener la CGImage UIImage *layerImage = [UIImage imageNamed:@"image.jpg"]; CGImageRef image = [layerImage CGImage]; //Poner la imagen en la layer [boxLayer setContents:(id)image];
- Cada layer tiene una coordenada Z para ver cual se pinta primero
[boxLayer setZPosition:-5];
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *t = [touches anyObject]; CGPoint p = [t locationInView:self.view]; [boxLayer setPosition:p]; }
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *t = [touches anyObject]; p = [t locationInView:self.view]; [boxLayer setPosition:p]; [boxLayer setNeedsDisplay]; }
1.Animation Objects
- Un objeto de animacin es un conjunto de instrucciones que cambian las propiedades de una instancia de CALayer. - Muchas de las propiedades de CALayer como opacidad, posicin, tamao, etc pueden ser animadas por los objetos de animacin utilizando una funcin de interpolacin. - Un ejemplo sera Muevete del punto A al punto B durante 2 segundos
1.Animation Objects
- En la practica, la forma de utilizar estos objetos de animacin es mediante alguna de las subclases que heredan de CAAnimation
- Imagen de fondo - 3 botones, cada uno con la imagen de un jugador - Cuando pulsemos en cada uno de esos botones la pelota se desplazar hacia el jugador
3.Timing functions
- En nuestro ejemplo la animacin comienza de repente porque se hace una interpolacin lineal - Podemos cambiar la funcin de interpolacin por otra diferente como por ejemplo una que comience aceleradamente y termine desacelerando
CAMediaTimingFunction *tf = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; [animacion setTimingFunction:tf];
4.Animation completion
- Asociar nuestro controlador como delegate de la animacin
[animacion setDelegate:self];
- Cuando la animacin termine se realizar una llamada al mtodo animationDidStop que deberemos sobreescribir para realizar una accin justo despus de que la animacin haya terminado.
6.More Animation
- Como hemos visto se pueden solapar varias animaciones en un mismo instante de tiempo - Extender el ejemplo anterior para que la pelota: - tarde 2 segundos en desplazarse de un jugador a otro - mientras tanto su alpha cambia de 0.0 a 1.0 durante 1 segundo - adems su escala cambia a lo largo de 2 segundos los valores 1,2,1 - que los pelotazos empiecen con velocidad y terminen en seco
1.Colorizing TouchDrawView
- Partiremos de nuestro ejemplo TouchDrawView - Vamos a utilizar bloques para pintar con diferentes colores
1.Colorizing TouchDrawView
- Antes de nada vamos a modicar la clase line para que almacene un color Line.h :
#import <Foundation/Foundation.h> @interface Line : NSObject { CGPoint begin; CGPoint end; UIColor *color; } @property(nonatomic) CGPoint begin; @property(nonatomic) CGPoint end; @property(nonatomic,retain) UIColor *color; @end
Line.m :
#import "Line.h" @implementation Line @synthesize begin,end; @synthesize color;
1.Colorizing TouchDrawView
- (void)encodeWithCoder:(NSCoder *)coder; { [coder encodeFloat:begin.x forKey:@"beginX"]; [coder encodeFloat:begin.y forKey:@"beginY"]; [coder encodeFloat:end.x forKey:@"endX"]; [coder encodeFloat:end.y forKey:@"endY"]; } - (id)initWithCoder:(NSCoder *)coder; { self = [[Line alloc] init]; if (self != nil) { color = [UIColor blackColor]; begin = CGPointMake([coder decodeFloatForKey:@"beginX"],[coder decodeFloatForKey:@"beginY"]); end = CGPointMake([coder decodeFloatForKey:@"endX"],[coder decodeFloatForKey:@"endY"]); } return self; } -(void)dealloc{ [color release]; } @end
1.Colorizing TouchDrawView
- En TouchDrawView.m, en el mtodo drawRect sustituiremos:
[[UIColor blackColor] set];
2.Blocks
- Trozos de cdigo que se pueden guardar en variables o pasar como argumentos - Tambin se pueden devolver como el resultado de un mensaje y ejecutar posteriormente - Los bloques capturan el entorno lxico, entenderemos que quiere decir esto unas transparencias ms adelante.
3.Blocks as variables
- Vamos a crear un mtodo que reciba como variable un bloque. - El nombre de esa variable la llamamos color - Dentro del mtodo usamos el bloque color si fuera una funcin
-(void)transformLineColorsWithBlock:(UIColor* (^)(Line*))color{ for (Line *l in lines) { UIColor *c = color(l); [l setColor:c]; } [self setNeedsDisplay]; }
3.Blocks as variables
- Despus crearemos un botn en la interface y lo enlazaremos con un mtodo que llamaremos colorear
-(IBAction)colorear:(id)sender{ UIColor *(^esquemaDeColor)(Line*)=^(Line *l) { float longitudX = l.end.x - l.begin.x; float longitudY = l.end.y - l.begin.y; /* Regla de tres 320 - 1.0 longitudX - r 480 - 1.0 longitudY - g */ float r=longitudX/320.0; float g=longitudY/480.0; float b=1.0; return [UIColor colorWithRed:r green:g blue:b alpha:1]; }; [self transformLineColorsWithBlock:esquemaDeColor]; }
4.Capturing variables
- Los bloques capturan el entorno lxico
-(void)metodo{ int value = 5; void (^aBlock)() = ^(void){ NSLog(@"valor=%d",value); }; aBlock(); //Imprime "valor=5" value = 10; aBlock(); } //Imprime "valor=5"
7.Categories
- Crear una categora consiste en coger una clase existente y aadirle mtodos que despus podrn ser utilizables sin tener que hacer subclassing - En nuestro ejemplo crearemos una clase de tipo NSObject y la llamaremos UIColor+Inverse UIColor+Inverse.h :
#import <Foundation/Foundation.h> #import <UIKit/UIKit.h> @interface UIColor (Inverse) -(UIColor*)colorInvertido; @end
7.Categories
UIColor+Inverse.m :
#import "UIColor+Inverse.h" @implementation UIColor (Inverse) -(UIColor*)colorInvertido{ CGColorRef cgCLR = [self CGColor]; const CGFloat *components = CGColorGetComponents(cgCLR); float r = 1.0 - components[0]; float g = 1.0 - components[1]; float b = 1.0 - components[2]; UIColor *colorInvertido = [UIColor colorWithRed:r green:g blue:b alpha:1.0]; return colorInvertido; } @end
7.Categories
- Para usarlo en nuestro ejemplo, en TouchDrawView.m importaremos la cabecera UIColor+Inverse.h - Ya podemos usar el mtodo colorInvertido con cualquier instancia de UIColor - Modiquemos el ejemplo anterior, para que el mtodo transformLineColorsWithBlock invierta el color devuelto por el bloque colorear antes de asignarlo al color de la linea
-(void)transformLineColorsWithBlock:(UIColor* (^)(Line*))color{ for (Line *l in lines) { UIColor *c = color(l); [l setColor:[c colorInvertido]]; } [self setNeedsDisplay]; }
1.Web Services
- Cualquier navegador de internet utiliza el protocolo HTTP para comunicarse con un servicio web. - La interaccin ms simple consiste en que el cliente enva una peticin sobre una URL especca al servidor y este le responde enviando el contenido de la pgina que se ha solicitado. - Para interacciones ms complejas el navegador puede incluir parmetros en su peticin. Estos parmetros son procesados por el servidor para enviar el contenido de una pgina dinmicamente construida con respecto a esos parmetros. - Usar un servicio web desde una aplicacin iOS requiere los siguientes pasos: - Formatear los datos para enviar como XML o JSON - Enviar los datos en una peticin HTTP - Recibir la respuesta HTTP - Parsear y procesar el los datos recibidos como XML o JSON
- Lector RSS - Una lista con noticias RSS obtenidas de un servidor. - Tocando sobre cada una de esos elementos podremos ver la noticia
- Crear proyecto de tipo Empty Application - Aadir una nueva clase de tipo NSObject y cambiar su padre para que herede de UITableViewController - Aadir a este chero mtodos requeridos de data source - En AppDelegate.m crear una instancia de ListViewController y asignarla como root view controller de un navigation controller. - Hacer el navigation controller el root view controller de window
- Asignamos nuestro controlador como delegate de la conexin - Despus debemos implementar una serie de mtodos en nuestro controlador para que se vayan recibiendo los datos
(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error (void)connectionDidFinishLoading:(NSURLConnection *)connection
5.Parsing XML
- Veamos un fragmento de lo que contiene un chero XML y lo que vamos a parsear
<item> <title>Entrevista a Atomic Flavor en Baquia TV</title> <link> http://www.atomicflavor.com/entrevista-a-atomic-flavor-en-baquia-tv/ </link> <comments> http://www.atomicflavor.com/entrevista-a-atomic-flavor-en-baquia-tv/ #comments </comments> <pubDate>Wed, 15 Jun 2011 09:28:48 +0000</pubDate>
- Vamos a usar NSXMLParser, que es la librera incluida por defecto en el SDK de iOS
5.Parsing XML
- 1. Implementar el protocolo NSXMLParserDelegate - 2. Declarar cadenas del XML - 3. Sobreescribir los mtodos de parseo - 4. Invocar comienzo de parseo
5.Parsing XML
- 1. Declarar cadenas de parseo
NSXMLParser * rssParser; NSMutableData *responseData; NSMutableArray *items;! NSMutableDictionary * item;! NSString * currentElement; NSMutableString NSMutableString NSMutableString NSMutableString * * * * currentTitle; currentDate; currentSummary; currentLink;
5.Parsing XML
- 2. Iniciar parseo
! NSString *str = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding]; ! NSData *data= [str dataUsingEncoding:NSUTF8StringEncoding]; items = [[NSMutableArray alloc] init]; ! ! ! ! ! ! ! rssParser = [[[NSXMLParser alloc] initWithData:data] autorelease]; [rssParser setDelegate:self]; [rssParser setShouldProcessNamespaces:NO]; [rssParser setShouldReportNamespacePrefixes:NO]; [rssParser setShouldResolveExternalEntities:NO]; [rssParser parse];!
5.Parsing XML
- 3. Sobreescribir mtodos del delegado NSXMLParserDelegate: - 3.1 Empieza parseo de elemento - 3.2 Encontrada cadena - 3.4 Termina parseo de elemento - 3.5 Terminado de parsear
5.Parsing XML
- 3.1 Empieza parseo de elemento
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName: (NSString *)qName attributes:(NSDictionary *)attributeDict { ! currentElement = [elementName copy]; ! ! if ([elementName isEqualToString:@"item"]) ! { ! ! item = [[NSMutableDictionary alloc] init]; ! ! currentTitle = [[NSMutableString alloc] init]; ! ! currentDate = [[NSMutableString alloc] init]; ! ! currentSummary = [[NSMutableString alloc] init]; ! ! currentLink = [[NSMutableString alloc] init]; ! } }
5.Parsing XML
- 3.2 Encontrada cadena
! ! ! ! ! ! ! } (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{ if ([currentElement isEqualToString:@"title"]) { ! [currentTitle appendString:string]; } else if ([currentElement isEqualToString:@"link"]) { ! [currentLink appendString:string]; } else if ([currentElement isEqualToString:@"pubDate"]) { ! [currentDate appendString:string]; }
5.Parsing XML
- 3.4 Termina parseo de elemento
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName: (NSString *)qName{ ! if ([elementName isEqualToString:@"item"]) { ! ! [item setObject:currentTitle forKey:@"title"]; ! ! [item setObject:currentLink forKey:@"link"]; ! ! [item setObject:currentDate forKey:@"pubDate"]; ! ! [items addObject:[item copy]]; ! } }
5.Parsing XML
- 3.5 Terminado de parsear
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError { ! NSLog(@"No se pudo parsear el XML"); } - (void)parserDidEndDocument:(NSXMLParser *)parser { ! [[self tableView] reloadData]; }
5.Parsing XML
- Por ltimo modicamos los mtodos de nuestro ListViewController para que muestren la lista de elementos recuperados
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection: (NSInteger)section{ return [items count]; } -(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath{ UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"UITableViewCell"]; if (cell == nil) { cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"UITableViewCell"] autorelease]; } NSMutableDictionary *i = [items objectAtIndex:indexPath.row]; [[cell textLabel] setText:[i objectForKey:@"title"]]; return cell; }
5.Parsing XML
- Tambin crearemos un mtodo para que podamos invocar el comienzo del parseo desde AppDelegate
-(void)comenzarConexion{ responseData = [[NSMutableData data] retain]; NSURL *baseURL = [[NSURL URLWithString:@"http://www.atomicflavor.com/ feed/"] retain]; NSURLRequest *request = [NSURLRequest requestWithURL:baseURL]; [[[NSURLConnection alloc] initWithRequest:request delegate:self] autorelease]; }
7.UIWebView
- Creamos una nueva clase de tipo NSObject y le cambiamos el padre para que herede de UIViewController - UIViewController.h :
#import <Foundation/Foundation.h> @interface WebViewController : UIViewController { } @property (nonatomic,readonly) UIWebView *webView; @end
7.UIWebView
- UIViewController.m :
#import "WebViewController.h" @implementation WebViewController @synthesize webView; - (void) loadView{ CGRect screenFrame = [[UIScreen mainScreen] applicationFrame]; UIWebView *wv = [[UIWebView alloc] initWithFrame:screenFrame]; [wv setScalesPageToFit:YES]; [self setView:wv]; [wv release]; } -(UIWebView*)webView { return (UIWebView*)[self view]; } @end
7.UIWebView
- Crear una propiedad en ListViewController para apuntar a WebViewController
WebViewController *webViewController; @property(nonatomic,retain) WebViewController *webViewController; @synthesize webViewController;
7.UIWebView
- Mtodo para cuando seleccionemos alguna la de ListViewController
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ //Desplazar la vista actual a webViewController [[self navigationController] pushViewController:webViewController animated:YES]; //Obtener el elemento NSMutableDictionary *i = [items objectAtIndex:indexPath.row]; //Limpiar cadena de parsitos finales NSString *cadenaURL = [i objectForKey:@"link"]; WSLog(@"[cadena =%@]",cadenaURL); cadenaURL = [cadenaURL substringToIndex:[cadenaURL length]-1]; cadenaURL = [cadenaURL stringByReplacingOccurrencesOfString:@" " withString:@""]; cadenaURL = [cadenaURL stringByReplacingOccurrencesOfString:@"\n" withString:@""]; WSLog(@"[cadena =%@]",cadenaURL); //Crear NSURL NSURL *url = [NSURL URLWithString:cadenaURL]; //Crear peticin con esa URL NSURLRequest *req = [NSURLRequest requestWithURL:url]; //Decirle a webviewcontroller que cargue esa peticin [[webViewController webView] loadRequest:req]; //Poner como ttulo del control de navegacin el ttulo de la noticia [[webViewController navigationItem] setTitle:[i objectForKey:@"title"]]; }
! !
8.NSXMLParser
- En este ejercicio hemos utilizado NSXMLParser que es el parseador disponible por defecto en la api del SDK de iOS. - En internet podremos encontrar otras libreras de terceros que tambin podremos usar para parsear chero XML sustituyendo a NSXMLParser - Algunas de las libreras de terceros que podremos encontrar disponibles son: - libxml2 - TBXML - TouchXML - KissXML - TinyXML - GDataXML
- Veamos como es en detalle cada una de las peticiones que realiza nuestro programa. - Hay tres partes, la linea de peticin, las cabeceras HTTP y el cuerpo HTTP
10.Credentials
- Cuando se accede a un servicio web, hay veces que es necesario identicarse para poder trabajar con dicho servicio.
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge { // Se ha fallado 2 veces if ([challenge previousFailureCount] > 1) { //Dar mensaje de aviso } else { // Responder NSURLCredential *cred = [[[NSURLCredential alloc] initWithUser:@"user" password:@"pass" persistence:NSURLCredentialPersistenceForSession] autorelease]; [[challenge sender] useCredential:cred forAuthenticationChallenge:challenge]; } }
11.More Data
- Vamos a crear una clase CustomCell que sea subclase de UTTableViewCell que tenga varios labels, uno para el ttulo y otro para la fecha.
CustomCell.h:
#import <UIKit/UIKit.h> @interface CustomCell : UITableViewCell { UILabel *titulo; UILabel *hora; } @property(nonatomic,retain) UILabel *titulo; @property(nonatomic,retain) UILabel *hora; @end
11.More Data
- Mtodo constructor
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; if (self) { //Instanciamos los labels titulo = [[UILabel alloc] initWithFrame:CGRectZero]; hora = [[UILabel alloc] initWithFrame:CGRectZero]; [titulo setBackgroundColor:[UIColor clearColor]]; [hora setBackgroundColor:[UIColor clearColor]]; //Los aadimos a el contenido de la vista [[self contentView] addSubview:titulo]; [[self contentView] addSubview:hora]; //Liberamos [titulo release]; [hora release]; } return self; }
11.More Data
- Colocacin de SubVistas
-(void)layoutSubviews{ [super layoutSubviews]; CGRect bounds = [[self contentView] bounds]; float inset = 5.0; float w = bounds.size.width; float h = bounds.size.height; CGRect titleFrame = CGRectMake(inset,inset, w, (h/2)); CGRect hourFrame = CGRectMake(inset,inset+h/2, w, (h/2)); [titulo setFrame:titleFrame]; [hora setFrame:hourFrame]; }
11.More Data
- Modicar cellForRowAtIndexPath de ListViewController.m
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ CustomCell *cell = (CustomCell*)[tableView dequeueReusableCellWithIdentifier:@"CustomCell"]; if (cell == nil) { cell = [[[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"CustomCell"] autorelease]; } NSMutableDictionary *i = [items objectAtIndex:indexPath.row]; [[cell titulo] setText:[i objectForKey:@"title"]]; [[cell hora] setText:[i objectForKey:@"pubDate"]]; return cell; }
12.More UIWebView
- Aadir UIActivityIndicatorView a nuestra clase WebViewController en el centro de la pantalla - Hay que implementar UIWebViewDelegate en nuestro controlador - Vamos a sobreescribir los mtodos de UIWebViewDelegate: - Cuando la noticia empiece a cargar en el centro de la pantalla deberemos ver un UIActivityIndicatorView con su animacin activada - Cuando la noticia se haya terminado la carga, el UIActivityIndicatorView desaparecer
12.More UIWebView
- Cambios sobre loadView
- (void) loadView{ CGRect screenFrame = [[UIScreen mainScreen] applicationFrame]; UIWebView *wv = [[UIWebView alloc] initWithFrame:screenFrame]; [wv setScalesPageToFit:YES]; [wv setDelegate:self]; activityIndicator = [[UIActivityIndicatorView alloc] init]; [activityIndicator setHidesWhenStopped:TRUE]; [activityIndicator stopAnimating]; [activityIndicator setBackgroundColor:[UIColor clearColor]]; [activityIndicator setColor:[UIColor blackColor]]; [self setView:wv]; [self.view addSubview:activityIndicator]; [activityIndicator setCenter:CGPointMake(self.view.bounds.size.width/ 2, self.view.bounds.size.height/2)]; [activityIndicator release]; [wv release]; }
12.More UIWebView
- Mtodos de UIWebViewDelegate:
- (void)webViewDidStartLoad:(UIWebView *)webView{ ! [activityIndicator startAnimating]; } - (void)webViewDidFinishLoad:(UIWebView *)webView{ [activityIndicator stopAnimating]; }
24.UISplitViewController
1.Splitting Up Nerdfeed
- Tanto iPhone como iPod Touch tienen un tamao de pantalla bastante limitado, por eso la manera usual de presentar las vistas es mediante un UINavigationController. - En cambio, el iPad tiene una pantalla mucho mayor y puede utilizar clases predenidas como UISplitViewController que slo estn disponible para iPad. - Para trabajar con UISplitViewController debemos tener dos controladores, el master y el detail. - El controlador master ocupar poco en la pantalla y ser una lista que nos permita elegir que contenido visualizar - El controlador detail ocupar la mayor parte de la pantalla y mostrar en detalle el contenido seleccionado en el master
1.Splitting Up Nerdfeed
1.Splitting Up Nerdfeed
- Partimos de el proyecto anterior - Realizamos cambios en AppDelegate para instanciar el UISplitViewController en caso de estar ejecutando el programa en un iPad - Conguramos los controladores para que soporten cambios a orientacin horizontal si el programa se esta ejecutando en un iPad
1.Splitting Up Nerdfeed
- Modicamos el mtodo didFinishLaunchingWithOptions del chero AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions { self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease]; // Override point for customization after application launch. self.window.backgroundColor = [UIColor whiteColor]; //Instanciar controllador ListViewController ListViewController *lvc = [[ListViewController alloc] initWithStyle:UITableViewStylePlain]; [lvc autorelease]; //Instanciar controlador de navegacion UINavigationController *masterNav = [[UINavigationController alloc] initWithRootViewController:lvc]; [masterNav autorelease]; WebViewController *wvc = [[[WebViewController alloc] init] autorelease]; [lvc setWebViewController:wvc]; ...
1.Splitting Up Nerdfeed
.... if ([[UIDevice currentDevice] userInterfaceIdiom] ==UIUserInterfaceIdiomPad){ //El detalle debe ir en un navigation controller UINavigationController *detailNav = [[UINavigationController alloc] initWithRootViewController:wvc]; [detailNav autorelease]; NSArray *vcs = [NSArray arrayWithObjects:masterNav,detailNav, nil]; UISplitViewController *svc = [[[UISplitViewController alloc] init] autorelease]; [svc setDelegate:wvc]; [svc setViewControllers:vcs]; [[self window] setRootViewController:svc]; } else { //Asignar como rootViewController el control de navegacin [[self window] setRootViewController:masterNav]; } [lvc comenzarConexion]; [self.window makeKeyAndVisible]; return YES; }
1.Splitting Up Nerdfeed
- Aadir el mtodo shouldAutorotateToInterfaceOrientation a ListViewController.m y WebViewController.m para que la app soporte orientacin horizontal
- (BOOL)shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)interfaceOrientation { if ([[UIDevice currentDevice] userInterfaceIdiom] ==UIUserInterfaceIdiomPad){ return YES; } else { return interfaceOrientation == UIInterfaceOrientationPortrait; } }
2.Master-Detail Communication
- Como desde ListViewController tenemos un puntero hacia WebViewController, podremos seguir indicando a este controlador la pgina que debe cargar - Por lo general en el master siempre tendremos un puntero hacia el detalle para modicar el contenido - En el caso de estar disponible un splitViewController tendremos quemodicar la forma de presentar el contenido cuando se seleccione un elemento de la lista. Para ello realizaremos el siguiente cambio en didSelectRowAtIndexPath:
if (![self splitViewController]) { [[self navigationController] pushViewController:webViewController animated:YES]; }
4.Universalizing Nerdfeed
- Ahora podemos probar con los diferentes simuladores de iPhone o iPad para ver como la aplicacin se comporta de forma diferente.
- Aplicacin multimedia - Reproducir chero de audio - Reproducir un sonido del sistema corto - Reproducir chero de video
2.System Sounds
- Los llamados sonidos del sistema son sonidos cortos sin comprimir que se utilizan tpicamente en las interfaces o cuando el usuario realiza alguna accin - El framework Auditoolbox nos permite registrar una serie de sonidos en el servidor de sonidos del sistema. Estos sonidos deben ser: - Menores a 30 segundos de duracin - Estar empaquetados en formato PCM o IMA4 - Ser de uno de los siguientes tipos: CAF, WAV o AIFF - Como pasar de mp3 a caf :
afconvert -f caff -d LEI16@44100 -c 1 sound.mp3 sound.caf
2.System Sounds
- Importar framework de AudioToolbox - Aadir objeto de tipo SystemSoundID ViewController.h :
#import <UIKit/UIKit.h> #import <AudioToolbox/AudioToolbox.h> @interface ViewController : UIViewController { SystemSoundID sonidoCorto; } -(IBAction)reproducirAudio:(id)sender; -(IBAction)reproducirSonidoCortoSistema:(id)sender; -(IBAction)reproducirVideo:(id)sender; @end
- Descargar sonido
AudioServicesDisposeSystemSoundID(sonidoCorto);
@interface ViewController : UIViewController<AVAudioPlayerDelegate> { SystemSoundID sonidoCorto; AVAudioPlayer *musica; MPMoviePlayerController *video; } -(IBAction)reproducirAudio:(id)sender; -(IBAction)reproducirSonidoCortoSistema:(id)sender; -(IBAction)reproducirVideo:(id)sender; @end
- Y lo reproducimos
-(IBAction)reproducirVideo:(id)sender{ [video play]; }
7.MPMoviePlayerViewController
- Si queremos presentar un vdeo en pantalla completa usaremos la clase MPMoviePlayerViewController y despus lanzaremos su presentacin
MPMoviePlayerViewController *playerViewController = [[MPMoviePlayerViewController alloc] initWithContentURL:movieURL]; [self presentMoviePlayerViewControllerAnimated:playerViewController];
8.Preloading video
- Cuando iniciamos la carga de un vdeo no est disponible de manera inmediata. Mas an si lo cargamos en streaming desde un servidor - Podemos aadir a nuestro objeto de vdeo una noticacin apuntando a un mtodo para que sea llamado cuando el vdeo se haya terminado de cargar completamente.
NSString *moviePath = [[NSBundle mainBundle] pathForResource:@"video" ofType:@"m4v"]; if (moviePath) { //Creamos un NSURL y lo cargamos en musica NSURL *movieURL = [NSURL fileURLWithPath:moviePath]; video = [[MPMoviePlayerController alloc] initWithContentURL:movieURL]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(displayPreloadedVideo:) name:MPMoviePlayerLoadStateDidChangeNotification object:video]; }
8.Preloading video
- El mtodo que aadimos para atender a esa noticacin
-(void)displayPreloadedVideo:(NSNotification*)note{ [self.view addSubview:video.view]; float h = self.view.bounds.size.height/2; float w = self.view.bounds.size.width; [video.view setFrame:CGRectMake(0, h, w, h)]; }
9.Background Processes
- Una aplicacin puede reproducir audio incluso si no es la aplicacin activa. - Para congurar este tipo de proceso de segundo plano debemos aadir a el chero Info.plist de nuestro proyecto el correspondiente modo de background. Par a ello aadimos un campo ms con el valor UIBackgroundModes. La clave que corresponde con la reproduccin de audio en segundo plano es App plays audio
9.Background Processes
- Para que la aplicacin pueda reproducir audio en segundo plano deberemos cambiar la categora de AVAudioSession. - La categora que permite reproducir audio en segundo plano es AVAudioSessionCategoryPlayback
NSString *musicPath = [[NSBundle mainBundle] pathForResource:@"music" ofType:@"mp3"]; if (musicPath) { //Creamos un NSURL y lo cargamos en musica NSURL *musicURL = [NSURL fileURLWithPath:musicPath]; //Cambiamos la categoria para reproducir audio en segundo plano [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil]; musica = [[AVAudioPlayer alloc] initWithContentsOfURL:musicURL error:nil]; [musica setDelegate:self]; }
12.Low-level APIs
- En este tema hemos visto la forma ms sencilla de reproducir vdeo y audio utilizando la API de alto nivel - Si queremos hacer cosas ms avanzadas como recodicar, aplicar ltros, efectos o lo que necesitemos deberemos utilizar las APIs de bajo nivel - Usaremos AudioToolbox y CoreAudio para los sonidos - Usaremos CoreVideo para el vdeo
13.Audio Recording
- Podemos grabar audio utilizando la clase AVAudioRecorder - Vamos a modicar nuestro ejemplo para aadir: - Un botn grabar que nos permita grabar - Un botn play que reproduzca el ltimo archivo grabado
13.Audio Recording
- Punteros necesarios
AVAudioPlayer *grabadoPlayer; AVAudioRecorder *grabadoRecorder; bool grabando;
-(IBAction)grabar:(id)sender; -(IBAction)reproducir:(id)sender;
13.Audio Recording
-(IBAction)grabar:(id)sender{ if (!grabando) { //Settings de grabar NSMutableDictionary *recordSettings [recordSettings setObject:[NSNumber [recordSettings setObject:[NSNumber [recordSettings setObject:[NSNumber [recordSettings setObject:[NSNumber [recordSettings setObject:[NSNumber [recordSettings setObject:[NSNumber = [[NSMutableDictionary alloc] initWithCapacity:10]; numberWithInt: kAudioFormatLinearPCM] forKey: AVFormatIDKey]; numberWithFloat:44100.0] forKey: AVSampleRateKey]; numberWithInt:2] forKey:AVNumberOfChannelsKey]; numberWithInt:16] forKey:AVLinearPCMBitDepthKey]; numberWithBool:NO] forKey:AVLinearPCMIsBigEndianKey]; numberWithBool:NO] forKey:AVLinearPCMIsFloatKey];
//Ponemos la sesion en modo grabacin AVAudioSession *audioSession = [AVAudioSession sharedInstance]; [audioSession setCategory:AVAudioSessionCategoryRecord error:nil]; NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *recDir = [[paths objectAtIndex:0] stringByAppendingFormat:@"/%@", @"fichero"]; NSURL *url = [NSURL fileURLWithPath:recDir]; if (grabadoRecorder!=nil) { [grabadoRecorder stop]; [grabadoRecorder release]; } grabadoRecorder = [[ AVAudioRecorder alloc] initWithURL:url settings:recordSettings error:nil]; if ([grabadoRecorder prepareToRecord] == YES) { grabando=true; [sender setTitle:@"Parar grabacin" forState:UIControlStateNormal]; [grabadoRecorder record]; } } else { grabando=false; [sender setTitle:@"Grabar" forState:UIControlStateNormal]; [grabadoRecorder stop]; }
13.Audio Recording
- Mtodo de reproduccin
-(IBAction)reproducir:(id)sender{ //Ponemos la sesion en modo reproduccin AVAudioSession *audioSession = [AVAudioSession sharedInstance]; [audioSession setCategory:AVAudioSessionCategoryPlayback error:nil]; NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *recDir = [[paths objectAtIndex:0] stringByAppendingFormat:@"/%@", @"fichero"]; NSURL *url = [NSURL fileURLWithPath:recDir]; if (grabadoPlayer!=nil) { [grabadoPlayer stop]; [grabadoPlayer release]; } grabadoPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil]; [grabadoPlayer play]; }
1.Push Notications
- Push Notications, mecanismo para enviar noticaciones a los usuarios que tengan instalada nuestra aplicacin - Podemos mostrar un mensaje corto - Podemos reproducir un sonido - Podemos cambiar el badge de el icono de la aplicacin
1.Push Notications
- Esquema de Push Notication
- Como lo usaremos
{"aps":{"alert":"Hello, world!","sound":"default"}}
3.Provisioning Proles
- Para habilitar push notications en tus aplicaciones, necesitan ser rmadas con un provisioning prole que est congurado para push. - Tu servidor necesita rmar las comunicaciones con los servidores APNS mediante un certicado SSL - Hay dos tipos de push server certicates: - Development - Production
7. Simplepush.php
<?php // Put your device token here (without spaces): $deviceToken = '0f744707bebcf74f9b7c25d48e3358945f6aa01da5ddb387462c7eaf61bbad78'; // Put your private key's passphrase here: $passphrase = 'curso'; // Put your alert message here: $message = 'My rst push notication!'; //////////////////////////////////////////////////////////////////////////////// $ctx = stream_context_create(); stream_context_set_option($ctx, 'ssl', 'local_cert', 'Certicado.pem'); stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase); // Open a connection to the APNS server $fp = stream_socket_client( ! 'ssl://gateway.sandbox.push.apple.com:2195', $err, ! $errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx); if (!$fp) ! exit("Failed to connect: $err $errstr" . PHP_EOL);
echo 'Connected to APNS' . PHP_EOL; // Create the payload body $body['aps'] = array( ! 'alert' => $message, ! 'sound' => 'default' ! ); // Encode the payload as JSON $payload = json_encode($body); // Build the binary notication $msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) . $payload; // Send it to the server $result = fwrite($fp, $msg, strlen($msg)); if (!$result) ! echo 'Message not delivered' . PHP_EOL; else ! echo 'Message successfully delivered' . PHP_EOL; // Close the connection to the server fclose($fp);
CONTACTO