CS 696 Mobile Phone Application DevelopmentFall Semester, 2010Doc 24 Gestures & MotionNov 30, 2010Copyright ©, All rights reserved. 2010 SDSU & Roger Whitney, 5500 Campanile Drive, San Diego, CA 92182-7700 USA. OpenContent (http://www.opencontent.org/opl.shtml) license defines the copyright on this document.References2Event Handling Guide for iOS, Apple documentationBeginning iPhone 3 Development, Mark & LaMarche, Chapters 13 & 153RespondersEvent is sent to view it occurs inIf it does not handle event it is passed on tosuper view (or controller)Views and Controllers are respondersResponder methods4- (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 *)eventtouches contains on UITouch object for each finger on screenUITouch5Getting the Location of Touches – locationInView: – previousLocationInView: view (property) window (property)Getting Touch Attributes tapCount (property) timestamp (property) phase (property)Getting a Touch Object’s Gesture Recognizers gestureRecognizers (property)Phases UITouchPhaseBegan UITouchPhaseMoved UITouchPhaseStationary UITouchPhaseEnded UITouchPhaseCancelledUIEvent6Getting the Touches for an Event – allTouches – touchesForView: – touchesForWindow:Getting Event Attributes timestamp (property)Getting the Event Type type (property) subtype (property)Getting the Touches for a Gesture Recognizer – touchesForGestureRecognizer:Types UIEventTypeTouches UIEventTypeMotion UIEventTypeRemoteControlSubtypes UIEventSubtypeNone UIEventSubtypeMotionShake UIEventSubtypeRemoteControlPlay UIEventSubtypeRemoteControlPause etc.Taps7- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { NSUInteger numberTaps = [[touches anyObject] tapCount]; }Counts as many taps as user doesTouches8- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { NSUInteger numberTouches = [[touches count]; }Up to 10 touches at onceSwipe 19Measure how long from start to end of touch eventsStart SwipeIf touch ends in here - horizontal swipeMin x change requiredMaxYchangeSample Code10- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *touch = [touches anyObject]; gestureStartPoint = [touch locationInView:self.view]; }- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *touch = [touches anyObject]; CGPoint currentPosition = [touch locationInView:self.view]; CGFloat deltaX = fabsf(gestureStartPoint.x - currentPosition.x); CGFloat deltaY = fabsf(gestureStartPoint.y - currentPosition.y); if (deltaX >= kMinimumGestureLength && deltaY <= kMaximumVariance) { tapsLabel.text = @"Horizontal swipe detected"; }}Gesture Recognizers11GestureUIKit classTapping (any number of taps)UITapGestureRecognizerPinching in and out (for zooming a view)UIPinchGestureRecognizerPanning or draggingUIPanGestureRecognizerSwiping (in any direction)UISwipeGestureRecognizerRotating (fingers moving in opposite directions)UIRotationGestureRecognizerLong press ( “touch and hold”)UILongPressGestureRecognizerSwipe12- (void) viewDidLoad { UISwipeGestureRecognizer *swipeGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeGesture:)]; [self.view addGestureRecognizer:swipeGesture]; [swipeGesture release];}- (IBAction) handleSwipeGesture: (UISwipeGestureRecognizer *) sender { NSLog(@"state %i", sender.state); touchesLabel.text = @"swiper";}Gesture Recognizer States13UIGestureRecognizerStatePossible Start state of gesture UIGestureRecognizerStateBegan UIGestureRecognizerStateChanged In middle of gestureUIGestureRecognizerStateEnded UIGestureRecognizerStateCancelled UIGestureRecognizerStateFailed UIGestureRecognizerStateRecognized = UIGestureRecognizerStateEndedGesture Recognizer Touches & Location14- (CGPoint)locationInView:(UIView *)view- (CGPoint)locationOfTouch:(NSUInteger)touchIndex inView:(UIView *)view– numberOfTouchesUIGestureRecognizer methodsPan Gesture Example15- (void) viewDidLoad { UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanGesture:)]; [self.view addGestureRecognizer:panGesture]; [panGesture release];}- (IBAction) handlePanGesture: (UIPanGestureRecognizer *) sender { NSLog(@"state %i", sender.state); CGPoint location = [sender locationInView:self.view]; NSLog(@"Location x: %f, y: %f", location.x, location.y ); NSLog(@"Number of touches %i", [sender numberOfTouches] );}Gesture Features16Have one gesture recognizer fail before another can start analyzing touch eventsPrevent other gesture recognizers from analyzing a specific multitouch sequence or a touch object in that sequence.Permit two gesture recognizers to operate simultaneously.Custom Gesture Recognizers17Can create gesture recognizer for custom gestures18Motion Events19Shake EventsShake motion events are sent to first responder- (BOOL)canBecomeFirstResponder { return YES;}- (void) viewDidLoad { [self becomeFirstResponder];}Motion Events20- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event{ NSLog(@"motion began"); }- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event{ NSLog(@"motion ended"); }- (void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event{ NSLog(@"touches cancelled"); }Orientation21UIDevice * device = [UIDevice currentDevice];[device beginGeneratingDeviceOrientationNotifications]; a bit laterUIDeviceOrientation orientation = device.orientation; when done[device endGeneratingDeviceOrientationNotifications];Possible Orientations22UIDeviceOrientationUnknownUIDeviceOrientationPortraitUIDeviceOrientationPortraitUpsideDownUIDeviceOrientationLandscapeLeftUIDeviceOrientationLandscapeRightUIDeviceOrientationFaceUpUIDeviceOrientationFaceDownAccelerometer23If use accelerometer must state so in Plist before submitting to AppleRequired device capabilitiesaccelerometerSingle instance of UIAccelerometerSet frequency of dataSet delegateStarting Accelerometer24#define kAccelerometerFrequency 20.0 //HzUIAccelerometer* theAccelerometer = [UIAccelerometer sharedAccelerometer];theAccelerometer.updateInterval
View Full Document