“Posibilidades” que ofrece el hardware en el iPhone!
25 febrero!
Ana C. Murillo!
Índice!
Sensores del iPhone!
• Multitouch!
• Vistas web, mapas, localización!
• Giróscopo, acelerómetro!
• Cámara!
Sensores del iPhone!Localización &
vistas-web!Cámara! Acelerómetros, giroscopo!
Multi-touch!
Eventos!UIEvent : Eventos de (multi-)touch, de movimiento y del control-remoto.typetypedef enum { UIEventTypeTouches, UIEventTypeMotion, UIEventTypeRemoteControl,} UIEventType;.subtypetypedef enum { UIEventSubtypeNone UIEventSubtypeMotionShake UIEventSubtypeRemoteControlPlay UIEventSubtypeRemoteControlPause UIEventSubtypeRemoteControlStop UIEventSubtypeRemoteControlTogglePlayPause UIEventSubtypeRemoteControlNextTrack UIEventSubtypeRemoteControlPreviousTrack UIEventSubtypeRemoteControlBeginSeekingBackward UIEventSubtypeRemoteControlEndSeekingBackward UIEventSubtypeRemoteControlBeginSeekingForward UIEventSubtypeRemoteControlEndSeekingForward} UIEventSubtype;
Eventos (multi)-touch!
• UIControlEvents (código o IB)!
(UIControl es la clase “base” para objetos de “control”: botones,…)!
Qué es cada evento? (ejemplo: ControlDemo)!
UIControlEventTouchDown
UIControlEventTouchDownRepeat
UIControlEventTouchDragInside
UIControlEventTouchDragOutside
UIControlEventTouchDragEnter
UIControlEventTouchDragExit
UIControlEventTouchUpInside
UIControlEventTouchUpOutside
UIControlEventTouchCancel
Eventos (multi)-touch!UITouch: representa un toque (un dedo sólo)!
@property(nonatomic,readonly) NSTimeInterval timestamp;
@property(nonatomic,readonly) UITouchPhase phase; (inicio, moviendo, parado, fin) @property(nonatomic,readonly) NSUInteger tapCount;
@property(nonatomic,readonly,retain) UIWindow *window;
@property(nonatomic,readonly,retain) UIView *view;- (CGPoint)locationInView:(UIView *)view; - (CGPoint)previousLocationInView:(UIView *)view;
UIEvent: contiene un conjunto de “toques”!@property(nonatomic,readonly) NSTimeInterval timestamp;-(NSSet *)allTouches;
-(NSSet *)touchesForWindow:(UIWindow *)window; -(NSSet *)touchesForView:(UIView *)view;
UIResponder: interface para objetos! ! !! que manejen eventos !(super de UIApplication, UIView, UIWindow…)!
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event; - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event; - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;
Eventos (multi)-touch!• Activar en UIView : property BOOL multipleTouchEnabled;!
Multiple-touch en una vista!
Touchs en varias vistas!
Eventos (multi)-touch!• Las subclases de UIView y UIViewController deben manejar (implementar)
todos los métodos relacionados con “touch” (y no se lo pasan al super), aunque sea null.!
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;
• Las demás subclases de elementos de UIKit pueden implementar los que se quiera, pero además deben pasar el evento al super! ! !![super touchesBegan:theTouches withEvent:theEvent];
Eventos (multi)-touch!
Ejemplo: MultiTouchDemo !
Eventos (multi)-touch!
Para los gestos típicos, más fácil! UIGestureRecognizer (abstract)
Actua de”supervisor” cada vez que ocurre un UITouch en una vista:!
UIView: @property(nonatomic,copy) NSArray *gestureRecognizers
subclasses de UIGestureRecognizer !• UITapGestureRecognizer• UIPinchGestureRecognizer• UIRotationGestureRecognizer• UISwipeGestureRecognizer• UIPanGestureRecognizer• UILongPressGestureRecognizer
Eventos (multi)-touch!
UIPanGestureRecognizer–"translationInView:!–"setTranslation:inView:!–"velocityInView:!
UIPinchGestureRecognizer@property CGFloat scale; !@property (readonly) CGFloat velocity!
UIRotationGestureRecognizer@propertyCGFloatrotation!@property (readonly) CGFloat velocity; !
UISwipeGestureRecognizer@property UISwipeGestureRecognizerDirection direction!@property NSUInteger numberOfTouchesRequired;!
UITapGestureRecognizer@property NSUInteger numberOfTapsRequired;!@property NSUInteger numberOfTouchesRequired;!
UILongPressGestureRecognizer@property(nonatomic) CFTimeInterval minimumPressDuration;!
! ! Los gestos tienen distintas propiedades y métodos para configurar y manejarlos. Algunos son:!Todos tienen!@property (readonly) UIGestureRecognizerState state; !(Possible, Began, Changed, Ended, Cancelled, Failed, Recognized)!
Se pueden “programar” nuevos “gestureRecognizer”!
Eventos (multi)-touch!
Añadir gestureRecognizer a UIView desde un Controller!
- (void)viewDidLoad{
UIView*panView=...; //Vista del controlador donde queremos reconocer gestos
UIGestureRecognizer *pangr = [[UIPanGestureRecognizer alloc] initWithTarget:panView action:@selector(pan:)];
[panView addGestureRecognizer:pangr];
[pangr release];}
• UIView: reconocer gestos !• Cualquier objeto: pedir a UIView que reconozca gestos (mensaje “addGesture…”). !• Normalmente UIView maneja los gestos reconocidos (no es obligatorio)!
Método del “target” para manejar el gesto!
Definir como “procesar” el evento!
- (void)pan:(UIPanGestureRecognizer *)recognizer{
if ((sender.state == UIGestureRecognizerStateChanged) || (sender.state == UIGestureRecognizerStateEnded)) { CGPoint translation = [recognizer translationInView:self];
! // mover algun elemento de la vista “afectada” (translation.x, translation.y)!! // e.g. si estamos en un grafico y el origen es una “property” origin!
self.origin = CGPointMake(self.origin.x+translation.x, self.origin.y+translation.y)
[recognizer setTranslation:CGPointZero inView:self]; }}
Eventos (multi)-touch!
Ejemplo Touches
Eventos (multi)-touch!
Eventos de movimiento! Eventos de movimiento!
Datos “preprocesados”!
• Evento“agitar”: UIEvent type;!@property(readonly) UIEventType @property(readonly) UIEventSubtype subtype; !
UIEventTypeMotion UIEventSubtypeMotionShake!
• Para “manejar” este evento: subclase de UIResponder que implemente!
- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event {} !
-(void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event!
-(void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event {} !
Y además sea “first responder”!- (BOOL)canBecomeFirstResponder {! return YES;! }!- (void)viewDidAppear:(BOOL)animated {! [self becomeFirstResponder];! }! !
Eventos de movimiento!Otros datos “preprocesados” de movimiento!• La orientación de las pantallas:!
en la clase UIApplication: statusBarOrientation (interface, no device orientation)!
en la clase UIViewController: propiedad interfaceOrientation !
- (BOOL)shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)interfaceOrientation!
• La orientación “real” del dispositivo: clase UIDevice **!! - Arrancar notificaciones: beginGeneratingDeviceOrientationNotifications!
Evento de cambio de orientación: UIDeviceOrientationDidChangeNotification (para “observadores registrados”)!" [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; !" [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector" (orientationChanged:)name:UIDeviceOrientationDidChangeNotification object:nil]; !
ó acceder a propiedad orientation!
! - Parar notificaciones: endGeneratingDeviceOrientationNotifications!
Eventos de movimiento!** !
clase UIDevice tambien proporciona:!(Instancia única +#currentDevice)!
• Opciones disponibles, versión, ID, OS … del dispositivo: !multitaskingSupported uniqueIdentifier name systemName systemVersion model
• Estado de la batería: batteryLevel batteryMonitoringEnabled batteryState
• Sensor de proximidad: proximityMonitoringEnabled proximityState !
Eventos de movimiento!
Ejemplo: AlternateViews!
“Control” de movimiento!Para eventos de movimiento mas detallados:!
Core Motion: acelerómetro y giróscopo !(sólo iPhone4 y iPod Touch nuevo).!antes UIAccelerometer class, esto es mas “completo”!
CMMotionManager:- solo una instancia por aplicación pero es un recurso para “todos”!- dos modos: samplear periódicamente la medición más reciente o suscribir un “manejador” para recibir todos los updates. (samplear más eficiente, mejor, salvo que “no se pueda perder ni una medida”)!
1 – Comprobar disponibilidad del hardware! ! ! ! @property (readonly) BOOL {accelerometer,gyro,deviceMotion}Available;
2 – Empezar la “captura” de datos.! - (void)start{Accelerometer,Gyro,DeviceMotion}Updates; (SOLO si vamos a acceder a los datos)
@property (readonly) BOOL {accelerometer,gyro,deviceMotion}Active; (comprobar si esta “en marcha”)
3 – “desconectar” la captura (cuanto antes!! ahorro de bateria)! - (void)stop{Accelerometer,Gyro,DeviceMotion}Updates;
Control de movimiento #(Core Motion)!
Acceder a los datos “en crudo”!
@property (readonly) CMAccelerometerData *accelerometerData;!Que contiene: @property (readonly) CMAcceleration acceleration;!typedef struct {double x;double y;double z;}CMAcceleration; !(incluye gravedad)!
@property (readonly) CMGyroData *gyroData;!Que contiene: @property (readonly) CMRotationRate rotationRate; !typedef struct { double x; double y; double z;} CMRotationRate; !(tiene un bias)!
@property (readonly) CMDeviceMotion *deviceMotion; (combinación de medida del gyro y acelerómetros)!
Control de movimiento #(Core Motion)!
Acceder a los datos “filtrados” instanciando CMDeviceMotion!
Datos de aceleración!@property (readonly) CMAcceleration gravity; !
@property(readonly) CMAccelerationuser Acceleration; !" //sin el “factor” gravedad gracias al giróscopo !typedef struct { double x; double y; double z; } CMAcceleration; // x, y, z in “g” !
Datos de rotación!@property CMRotationRate rotationRate; !" //sin bias respecto a datos “crudos” gracias al acelerómetro !typedef struct {double x;double y;double z;} CMRotationRate; !
@property CMAttitude *attitude; //orientación en 3D del dispositivo !
Control de movimiento #(Core Motion)!
Control de movimiento #(Core Motion)!
Activar y samplear después (normalmente en bucle de aplicación)!
- (void)startAccelerometerUpdates; !@property NSTimeInterval accelerometerUpdateInterval; !
- (void)startGyroUpdates; !@property NSTimeInterval gyroUpdateInterval; !
- (void)startDeviceMotionUpdates; !@property NSTimeInterval deviceMotionUpdateInterval; !
A partir de aquí, Core Motion actualiza la propiedad correspondiente del “UIMotionManager” con la medida más actual.!
Control de movimiento #(Core Motion)!
Registrar “bloques” para recibir “updates” de las medidas (métodos del único CMMotionManager)!
- (void)startAccelerometerUpdatesToQueue:(NSOperationQueue *)queue withHandler:(CMAccelerometerHandler)handler; !
- (void)startGyroUpdatesToQueue:(NSOperationQueue *)queue withHandler:(CMGyroHandler)handler; !
- (void)startDeviceMotionUpdatesToQueue:(NSOperationQueue *)queue withHandler:(CMDeviceMotionHandler)handler; !
Mostrar contenido web!
Mostrar contenido web!Usamos UIWebView (subclase de UIView)!
• Un navegador dentro de una “View”: no sólo HTML, también otros ficheros como PDF, imágenes,...!
• Distintos contenidos: !
cadena HTML local: !
datos + MIME type:!
URL remota:!
• Permite: cargar y navegar, delegar parte de los controles, ejecutar JavaScript (5 sec. de ejecución y hasta 10 MB de memoria)!
- (void)loadData:(NSData *)data MIMEType:(NSString *)MIMEType textEncodingName:(NSString *)encodingNamebaseURL:(NSURL *)baseURL;MIME: Multimedia Internet Mail Extensionmanera standard para denominar ciertos tipos de ficheros (PDF,...)NSURL: básicamente NSString, con un formato obligado, p.ej. “file://...” or “http://...”
- (void)loadHTMLString:(NSString *)string baseURL:(NSURL *)baseURL;
- (void)loadRequest:(NSURLRequest *)request;
UIWebView!
@property BOOL loading; !
@property BOOL canGoBack; !
@property BOOL canGoForward;!
@property BOOL scalesPageToFit; !
@property UIDataDetectorTypes dataDetectorTypes; !
(UIDataDetectorTypePhoneNumber/Link/Address/CalendarEvent: abre automático lo que corresponda)!
Capacidades de “browser”!
- (void)reload; !
- (void)stopLoading; !
- (void)goBack; !
- (void)goForward;!
! !
Mostrar contenido web!
Usamos MKMapView (subclase de UIView)!
• Muestra un mapa (googleMaps)!
• Con anotaciones, que se muestran con MKAnnotationView (e.g. MKPinAnnotationView, cualquier objeto puede ser una anotación siempre que implemente el protocolo MKAnnotation (tiene coordenadas y opcional título y subtítulo) !
• Cada anotación: puede ventana/mensaje asociada al hacer click. Por defecto: título y subtítulo. Se pueden añadir elementos a los lados (aquí UIImageView a izq., UIButton a dch.)!
Mapas Web: MAP KIT!• MKAnnotationView: “view” que dibuja el pin o marcador de la
anotación en el mapa.!
• Muy flexible: !
- configurar el tipo de mapa (@property MKMapType), mostrar posición de usuario (@property BOOL showsUserLocation), !
- controlar región de mapa mostrada (@property MKCoordinateRegion region), !
- pasar de latitud-longitud a posición de mapa, y viceversa ( -(CGPoint)convertCoordinate:(CLLocationCoordinate2D)coord
toPointToView:(UIView *)view;)!
• MKMapViewDelegate para manejar cambios en la región mostrada!
Mapas Web: MAP KIT!
• Localización de 3 sensores: GPS + Wifi + Red de móviles. Cuanto más preciso más gasto de bateria. Se comprueban/complementan todos los posibles.!
• Clase básica: CLLocation!
@property (readonly) CLLocationCoordinate2D coordinate; !@property(readonly) CLLocationDistance altitude; !
@property (readonly) CLLocationAccuracy horizontalAccuracy; // metros!@property (readonly) CLLocationAccuracy verticalAccuracy; // metros!(kCLLocationAccuracyBestForNavigation; kCLLocationAccuracyBest; kCLLocationAccuracyNearestTenMeters;
kCLLocationAccuracyHundredMeters; kCLLocationAccuracyKilometer; kCLLocationAccuracyThreeKilometers;) !
Y velocidad, orientación, timestamp,… !
- (CLLocationDistance)distanceFromLocation:(CLLocation *)otherLocation; //metros !
localización: CORE LOCATION!
Crear un CLLocationManager: alloc/init + configurar + arrancar!
• Comprobar que tenemos el hardware necesario.!" @property BOOL headingAvailable; !" @property BOOL locationServicesEnabled; !
• Crear CLLocationManager y establecer el “delegado”.!" CLLocationManager *clm = [[CLLocationManager alloc] init]; !
" @property(assign, nonatomic) id <CLLocationManagerDelegate> delegate;!
• Configurar el manager!clm.distanceFilter=10.0; //minimumdistancechangetoreport,inmeters !clm.desiredAccuracy = kCLLocationAccuracyTenMeters; !
• Arrancar la monitorización de los cambios:!! Monitorización continua: ! [clm startUpdatingLocation]; !
" Monitorización de cambios “significativos”: - (void)startMonitoringSignificantLocationChanges; !" Monitorización por zonas: - (void)startMonitoringForRegion:(CLRegion *) desiredAccuracy:(CLLocationAccuracy);!" Monitorización de la orientación:! - (void)startUpdatingHeading; !
localización: CORE LOCATION!
• El delegado del “manager recibira las notificaciones, por ejemplo:!- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)
newLocationfromLocation:(CLLocation *)oldLocation; !
- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading; !
• También se puede acceder directamente!CLLocation *location = clm.location; !CLHeading *heading = clm.heading; !
• Manejar errores/interferencias!
• Solicitar permiso al usuario para usar servicios de localización!
localización: CORE LOCATION! localización: CORE LOCATION!
Ejemplo Locations!
Acceso a la cámara!
• Clase UIImagePickerController (sin subclases, maneja interacciones con los UIViewController)!
• Protocolo UIImagePickerControllerDelegate (implementado por el delegado)!
• Configurar : ¿qué ocurre si se acepta la imagen o se cancela? ¿se puede editar antes de aceptar?!
• Comprobar disponibilidad de cámara: seleccionar imagen del dispositivo disponible (cámara o archivo). !
Acceso a la cámara!
Acceso a la cámara!
DEMO: añadir imagen desde archivo!
Acceso a la cámara!
Ejemplo: PhotoPicker!
Recordar …!
CUIDADO! con el gasto de batería: desconectar servicios en cuanto no se estén utilizando.!
Top Related