Upload
erikoterice
View
214
Download
0
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