46
 Curso de desarrollo iOS (principiante) sábado 4 de febrero de 12

Apuntes de AppCity 2012 Día 2

Embed Size (px)

DESCRIPTION

Apuntes de AppCity 2012 Día 2

Citation preview

  • Curso de desarrollo iOS(principiante)

    sbado 4 de febrero de 12

  • DA 2

    Delegation and Core Location Mapkit and Text Input Subclassing UIView and UIScrollView View Controllers Notification and Rotation

    sbado 4 de febrero de 12

  • 4. DELEGATION AND CORE LOCATION

    Este tema lo vamos a explicar usando como ejemplo un proyecto llamado WhereamI.

    Algunos aspectos bsicos de XCode.

    Al final del tema habremos aprendido qu es y para qu sirven los delegados, y a localizar nuestra posicin dentro de un mapa gracias al framework Core Location.

    sbado 4 de febrero de 12

  • Un proyecto es un archivo que contiene un conjunto de referencias a otros archivos.

    Extensin .xcodeproj

    Todo proyecto tiene al menos un target. Un target usa los archivos del proyecto para construir una aplicacin. Cuando hacemos Build and Run, compilamos y ejecutamos el target, no el proyecto.

    4. PROYECTOS, TARGETS Y FRAMEWORKS

    sbado 4 de febrero de 12

  • sbado 4 de febrero de 12

  • 4. PROYECTOS, TARGETS Y FRAMEWORKS

    Un framework es una coleccin de clases que se puede aadir a un target.

    Cocoa Touch es una coleccin de frameworks.

    Tenemos que aadir CoreLocation.framework, para poder acceder a las clases necesarias para la gestin de la localizacin geogrfica del dispositivo.

    sbado 4 de febrero de 12

  • Fin

    4. PROYECTOS, TARGETS Y FRAMEWORKS

    sbado 4 de febrero de 12

  • Adems del framework, tenemos que incluir el archivo de cabecera en el .h del delegate y aadir una instancia a CLLocationManager:

    #import

    @interface WhereamiAppDelegate : NSObject { CLLocationManager *locationManager; } @property (nonatomic, retain) IBOutlet UIWindow *window; @end

    CLLocationManager es la clase que interfiere con el hardware de localizacin del dispositivo

    4. PROYECTOS, TARGETS Y FRAMEWORKS

    sbado 4 de febrero de 12

  • Abrimos WhereamiAppDelegate.m y aadimos en el mtodo application:didFinishLaunchingWithOptions:

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    locationManager = [[CLLocationManager alloc] init]; [locationManager setDelegate:self];[locationManager setDistanceFilter:kCLDistanceFilterNone]; //metros, km...[locationManager setDesiredAccuracy:kCLLocationAccuracyBest]; //precisin[locationManager startUpdatingLocation];[[self window] makeKeyAndVisible]; return YES; }

    4. PROYECTOS, TARGETS Y FRAMEWORKS

    sbado 4 de febrero de 12

  • //Se actualiza el valor de newLocation cada vez que cambiamos de posicin- (void)locationManager:(CLLocationManager *)manager

    didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation{

    NSLog(@"%@", newLocation);}

    //Si se produce un error- (void)locationManager:(CLLocationManager *)managerdidFailWithError:(NSError *)error{

    NSLog(@"Could not find location: %@", error);}

    4. PROYECTOS, TARGETS Y FRAMEWORKS

    sbado 4 de febrero de 12

  • //Liberamos los recursos

    - (void)dealloc{if ([locationManager delegate] == self)

    [locationManager setDelegate:nil];[locationManager release];[_window release];[super dealloc];}

    4. PROYECTOS, TARGETS Y FRAMEWORKS

    sbado 4 de febrero de 12

  • Delegation, es un patrn de diseo muy usado en Cocoa Touch.

    Muchas clases tienen la propiedad delegate.

    Cada vez que se produce un evento en un objeto, se llama al mtodo que gestiona este evento en la clase que lo implementa. Se puede llamar a varios mtodos, por ejemplo, cuando ocurre un error.Los objetos delegados le dejan la responsabilidad de tratar sus eventos al objeto que lo implementa.

    @interface MapController : UIViewController

    4. DELEGATION

    sbado 4 de febrero de 12

  • Es una lista de declaraciones de mtodos que puede ser implementado por una clase.

    En iOS, los protocolos se utilizan con frecuencia para implementar objetos delegados.

    @protocol MyProtocol - (void)myProtocolMethod; @end

    4. PROTOCOLOS

    sbado 4 de febrero de 12

  • Se ejecuta cuando lanzamos una aplicacin desde XCode.

    Monitoriza el estado de la aplicacin: qu metodo se est ejecutando, el valor de las variables.

    Como sabemos lo que est pasando en cada momento, nos puede ayudar a resolver problemas o a corregir bugs.

    Elementos del debugger: - breakpoint: permite parar la ejecucin del programa en un punto determinado.- debug navigator: es una pila de procesos, donde podemos ver qu metodos se han ido llamando desde el main.- variables view: para ver el valor de las variables.- debugger bar: para controlar la ejecucin de nuestro programa, con controles de continuar, continuar a la siguiente lnea, continuar dentro del mtodo...

    4. DEBUGGER

    sbado 4 de febrero de 12

  • Como ejercicio, pon un punto de ruptura en varios sitios del programa.

    Familiarzate con cada uno de los elementos.

    Provoca una excepcin y comprueba el resultado en la ventana Output.

    4. DEBUGGER

    sbado 4 de febrero de 12

  • - Compilar Fuentes: en esta fase se usan todos los archivos fuentes que hemos aadido a nuestro proyecto.

    - Enlazar binarios: una vez que el cdigo fuente es compilado, este es enlazado con los frameworks (libreras)

    - Empaquetar recursos: tras compilar y enlazar, se crea un ejecutable en la carpeta Products de nuestro proyecto.

    4. FASES DE CONSTRUCCIN

    sbado 4 de febrero de 12

  • - Errores de compilacin: si el compilador se encuentra con cdigo que no entiende, emite un error y no permite que se ejecute. Pueden ser escribir mal una palabra, omitir alguna puntuacin necesaria

    - Errores de ejecucin: son errores que se producen durante la ejecucin del programa. Se producen cuando se intentan hacer operaciones que son imposibles de resolver, por ejemplo, dividir por cero o acceder a zonas de memoria que no tienen nada.

    4. TIPOS DE ERRORES

    sbado 4 de febrero de 12

  • Es invocado por el compilador antes de que se empiece la traduccin real a cdigo objeto.

    En esta fase de preprocesado se eliminan comentarios y se incluyen otros archivos.

    En #import se sustituye esta lnea por todo el contenido del fichero UIKit.h

    4. PREPROCESADOR

    sbado 4 de febrero de 12

  • Core Location nos muestra donde estamos en el mundo. MapKit es ese mundo.

    Casi todo el trabajo de MapKit se hace con la clase MKMapView.

    Hay que importar la librera: #import

    5. MAPKIT Y TEXT INPUT

    sbado 4 de febrero de 12

  • 5. CREAMOS EL INTERFAZ

    sbado 4 de febrero de 12

  • En el WhereamiAppDelegate.h

    #import #import #import

    @interface WhereamiAppDelegate : NSObject { CLLocationManager *locationManager; IBOutlet MKMapView *worldView; IBOutlet UIActivityIndicatorView *activityIndicator; IBOutlet UITextField *locationTitleField;}

    @property (nonatomic, retain) IBOutlet UIWindow *window;

    - (void)findLocation;- (void)foundLocation:(CLLocation *)loc;

    @end

    sbado 4 de febrero de 12

  • En el WhereamiAppDelegate.m

    En application:didFinishLaunchingWithOptions: aadimos:[worldView setShowsUserLocation:YES];

    y comentamos:// [locationManager startUpdatingLocation];

    - (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation{ NSLog(@"%@", newLocation);

    //Cada cuantos segundos queremos nuestra posicin? NSTimeInterval t = [[newLocation timestamp] timeIntervalSinceNow]; if (t < -180) { //ejemplo: 3 minutos return; } [self foundLocation:newLocation];}

    sbado 4 de febrero de 12

  • - (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)u{ CLLocationCoordinate2D loc = [u coordinate]; MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(loc, 250, 250); [worldView setRegion:region animated:YES];}

    - (BOOL)textFieldShouldReturn:(UITextField *)tf{ [self findLocation]; [tf resignFirstResponder]; return YES;}

    - (void)findLocation{ [locationManager startUpdatingLocation]; [activityIndicator startAnimating]; [locationTitleField setHidden:YES];}

    sbado 4 de febrero de 12

  • - (void)foundLocation:(CLLocation *)loc{ CLLocationCoordinate2D coord = [loc coordinate]; MapPoint *mp =[[MapPoint alloc] initWithCoordinate:coord title:[locationTitleField text]]; [worldView addAnnotation:mp]; [mp release]; // Hacemos zoom a la regin deseada MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(coord, 250, 250); [worldView setRegion:region animated:YES]; [locationTitleField setText:@""]; [activityIndicator stopAnimating]; [locationTitleField setHidden:NO]; [locationManager stopUpdatingLocation];}

    sbado 4 de febrero de 12

  • sbado 4 de febrero de 12

  • MapPoint.h

    #import #import #import

    @interface MapPoint : NSObject { NSString *title; CLLocationCoordinate2D coordinate;}

    // A new designated initializer for instances of MapPoint- (id)initWithCoordinate:(CLLocationCoordinate2D)c title:(NSString *)t;

    // This is a required property from MKAnnotation@property (nonatomic, readonly) CLLocationCoordinate2D coordinate;

    // This is an optional property from MKAnnotation@property (nonatomic, copy) NSString *title;

    @end

    sbado 4 de febrero de 12

  • MapPoint.m

    #import "MapPoint.h"

    @implementation MapPoint

    @synthesize coordinate, title;

    - (id)initWithCoordinate:(CLLocationCoordinate2D)c title:(NSString *)t{ self = [super init]; if (self) { coordinate = c; [self setTitle:t]; } return self;}

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

    @end

    sbado 4 de febrero de 12

  • Qu es un UIView? Es una instancia de UIView o una de sus subclases.

    Una vista sabe como dibujarse a si misma en el window de la aplicacin.

    Las vistas soportan Touch Events.

    Las vistas se colocan sobre el window de la aplicacin y sobre ellas mismas como subvistas

    6. SUBCLASSING UIVIEW Y UISCROLLVIEW

    sbado 4 de febrero de 12

  • Creamos un proyecto nuevo y lo llamamos Hypnosister. (Window Based Application).

    Aadimos un nuevo archivo (Objective-C Class) Subclase de UIView.

    Todas las subclases de UIView llevan implementado el mtodo drawRect, que contiene cdigo para dibujar en la vista.

    Por ejemplo, el mtodo drawRect de UIButton, dibuja un rectngulo con las esquinas redondeadas con una cadena de texto en el centro.

    Nosotros podemos editar nuestros propios mtodos drawRect.

    6. DRAWRECT

    sbado 4 de febrero de 12

  • - (void)drawRect:(CGRect)rect{ CGRect bounds = [self bounds]; // Dnde est el centro? CGPoint center; center.x = bounds.origin.x + bounds.size.width / 2.0; center.y = bounds.origin.y + bounds.size.height / 2.0; // distancia desde el centro hasta las esquinas float maxRadius = hypot(bounds.size.width, bounds.size.height) / 2.0; // Obtenemos el contexto sobre el que dibujaremos CGContextRef context = UIGraphicsGetCurrentContext(); // El ancho de las lneas es de 10 puntos CGContextSetLineWidth(context, 10); // El color del trazo [[UIColor lightGrayColor] setStroke];

    // Dibujamos crculos concntricos de fuera a dentro for (float currentRadius = maxRadius; currentRadius > 0; currentRadius -= 20) { CGContextAddArc(context, center.x, center.y, currentRadius, 0.0, M_PI * 2.0, YES); CGContextStrokePath(context); }

    sbado 4 de febrero de 12

  • NSString *text = @"You are getting sleepy."; // Creamos la fuente UIFont *font = [UIFont boldSystemFontOfSize:28]; // Dnde vamos a dibujar el texto? CGRect textRect; textRect.size = [text sizeWithFont:font]; textRect.origin.x = center.x - textRect.size.width / 2.0; textRect.origin.y = center.y - textRect.size.height / 2.0; // Ponemos el color de relleno del contexto actual a negro [[UIColor blackColor] setFill]; // Dibujamos una sombra 4 puntos a la derecha y 3 puntos abajo de color gris y radio 2.0 CGSize offset = CGSizeMake(4, 3); CGColorRef color = [[UIColor darkGrayColor] CGColor]; CGContextSetShadowWithColor(context, offset, 2.0, color); // Dibujamos el texto [text drawInRect:textRect withFont:font];}

    sbado 4 de febrero de 12

  • Aadimos a nuestro delegado la vista creada:

    #import

    @class HypnosisView;

    @interface HypnosisterAppDelegate : NSObject { HypnosisView *view;}

    @property (nonatomic, retain) IBOutlet UIWindow *window;

    @end

    sbado 4 de febrero de 12

  • Aadimos nuestra vista dentro de un ScrollView:

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{ // Hacemos un CGRect con el tamao de la ventana CGRect wholeWindow = [[self window] bounds]; UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:wholeWindow]; [[self window] addSubview:scrollView]; // Creamos la vista el doble de grande que la ventana CGRect reallyBigRect; reallyBigRect.origin = CGPointZero; reallyBigRect.size.width = wholeWindow.size.width * 2.0; reallyBigRect.size.height = wholeWindow.size.height * 2.0; [scrollView setContentSize:reallyBigRect.size];

    sbado 4 de febrero de 12

  • // Centramos nuestra vista en el scrollview CGPoint offset; offset.x = wholeWindow.size.width * 0.5; offset.y = wholeWindow.size.height * 0.5; [scrollView setContentOffset:offset]; // Habilitamos el zoom [scrollView setMinimumZoomScale:0.5]; [scrollView setMaximumZoomScale:5]; [scrollView setDelegate:self]; // Creamos la vista view = [[HypnosisView alloc] initWithFrame:reallyBigRect]; [view setBackgroundColor:[UIColor clearColor]]; [scrollView addSubview:view]; [scrollView release]; [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationFade]; [[self window] makeKeyAndVisible]; return YES;}

    sbado 4 de febrero de 12

  • sbado 4 de febrero de 12

  • Aadimos el mtodo delegado para habilitar el zoom en nuestra vista view:

    - (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView{ return view;}

    Listo! ahora ejecutamos nuestra aplicacin y probamos el zoom con la tecla alt pulsada y haciendo click con el botn izquierdo del ratn sin soltar.

    sbado 4 de febrero de 12

  • Hasta ahora hemos visto aplicaciones con una vista y un controlador.

    En este captulo veremos como hacer aplicaciones con varios controladores y varias vistas.

    Los controladores tienen una vista que es aadida al window.

    Heredan de UIViewController.

    Para entender los controladores de vistas, usaremos dos ejemplos:

    6. VIEW CONTROLLERS

    sbado 4 de febrero de 12

  • EJEMPLO PRACTICO 1

    Crear un proyecto para iPad con un UIView.

    Aadir 2 controladores y en cada uno de sus XIB meter un label.

    Despus desde el controlador principal cargar uno u otro segn est la posicin de un UISegmentedButton

    sbado 4 de febrero de 12

  • EJEMPLO PRACTICO 1

    Cargar un controlador y aadirlo a una vista

    ! controlador1=[[Controlador1 alloc] initWithNibName:@"Controlador1" bundle:nil];

    ! [vistaControladores addSubview:controlador1.view];

    sbado 4 de febrero de 12

  • EJEMPLO PRACTICO 1

    Quitar la vista de un controlador y liberarlo

    [controlador.view removeFromSuperview];[controlador release];controlador=nil;

    sbado 4 de febrero de 12

  • EJEMPLO PRACTICO 2

    Crear un proyecto para iPhone con una UITabBar y 2 controladores diferentes.

    Segn toquemos en uno u otro de los botones inferiores se nos cargar una de las vistas de manera automtica.

    Es otra forma de hacer lo del ejemplo practico 12.

    sbado 4 de febrero de 12

  • EJEMPLO PRACTICO 2

    Selecionar 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;

    }

    }

    sbado 4 de febrero de 12

  • Las notificaciones sirven para detectar cambios de estado en las propiedades de una clase.

    La idea del ejemplo es la siguiente: Tenemos un objeto A de una clase X, del que queremos ser avisados cuando una propiedad sea modificada, para ello avisaremos a otro objeto B, para que ste ltimo realice alguna accin. Para ello usaremos notificaciones, el objeto A enviar una notificacin cuando cambie su propiedad y el objeto B estar pendiente de dichas notificaciones.

    Usamos el centro de notificaciones por defecto de nuestra aplicacin y el mtodo postNotificationName:object: para enviar la notificacin. Los parmetros son el nombre de la notificacin y el objeto que la enva.

    7. NOTIFICATIONS AND ROTATIONS

    sbado 4 de febrero de 12

  • Para enviar una notificacin desde la clase A:

    - (void)enviarEvento {valor = 1;

    [[NSNotificationCenter defaultCenter] postNotificationName:@"Cambio Valor" object:self];}

    Para recibir la notificacin desde la clase B:

    - (void)viewDidLoad { [super viewDidLoad]; [[NSNotificationCenter defaultCenter] addObserver:self

    selector:@selector(seHaCambiadoValor)

    name:@"Cambio Valor" object:nil];

    }

    -(void)seHaCambiadoValor{NSLog(@"La variable valor tiene un 1");

    }

    7. NOTIFICATIONS AND ROTATIONS

    sbado 4 de febrero de 12

  • La rotacin nos permitir definir de que forma girar nuestra aplicacin si es que est permitido que gire:

    Si queremos que solo se permita el giro en modo apaisado usaremos:

    - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{

    return UIInterfaceOrientationIsLandscape(interfaceOrientation);}

    Si queremos que solo rote en podo retrato, usaremos:

    return UIInterfaceOrientationIsPortrait(interfaceOrientation);

    7. NOTIFICATIONS AND ROTATIONS

    sbado 4 de febrero de 12

  • Adems, tenemos que configurar la rotacin en el XCode. Seleccionamos el proyecto, el target y en la pestaa Summary:

    Esto nos generar en el archivo .plist (pestaa info):

    7. NOTIFICATIONS AND ROTATIONS

    sbado 4 de febrero de 12