180 likes | 188 Views
EEC-492/693/793 iPhone Application Development. Lecture 16 Wenbing Zhao & Nigamanth Sridhar. Outline. Taps, touches and gestures Terminology UITouch UIEvent UIResponder Apps in chapter 13 Assignment: Build the set of apps in chapter 13. 12/20/2019. 2.
E N D
EEC-492/693/793iPhone Application Development Lecture 16 Wenbing Zhao & Nigamanth Sridhar EEC492/693/793 - iPhone Application Development
Outline Taps, touches and gestures Terminology UITouch UIEvent UIResponder Apps in chapter 13 Assignment: Build the set of apps in chapter 13 12/20/2019 2 EEC492/693/793 - iPhone Application Development EEC492/693/793 - iPhone Application Development
Taps, Touches and Gestures • Gesture: any sequence of events that happens from the time you touch the screen with one or more fingers until you lift your figures off the screen • Touch: refers to a finger being placed on the screen • One finger, one touch • Tap: you touch the screen with a single finger and then immediately lift your finger off the screen without moving it around EEC492/693/793 - iPhone Application Development
The Responder Chain UIApplication Application Window • Events get passed through the responder chain • First responder: usually the object with which the user is currently interacting • If a responder in the chain doesn’t handle a particular event, it passes that event up the responder chain View Controller View superview View Controller View superview View Controller View View hierarchy Event EEC492/693/793 - iPhone Application Development
UITouch • Represents a single finger @property(nonatomic,readonly) NSTimeInterval timestamp; // indicates whether the touch began, moved, ended, or was canceled @property(nonatomic,readonly) UITouchPhase phase; @property(nonatomic,readonly) NSUInteger tapCount; @property(nonatomic,readonly,retain) UIWindow *window; @property(nonatomic,readonly,retain) UIView *view; // The view in which the touch initially occurred - (CGPoint)locationInView:(UIView *)view; // The view in which the touch initially occurred - (CGPoint)previousLocationInView:(UIView *)view; EEC492/693/793 - iPhone Application Development
UIEvent • A container for one or more touches @property(nonatomic,readonly) NSTimeInterval timestamp; - (NSSet *)allTouches; - (NSSet *)touchesForWindow:(UIWindow *)window; - (NSSet *)touchesForView:(UIView *)view; EEC492/693/793 - iPhone Application Development
Window A UITouch UIEvent View A UITouch View B UITouch Window B UITouch View C UIEvent - (NSSet *)allTouches; EEC492/693/793 - iPhone Application Development
Window A UITouch UIEvent View A UITouch View B UITouch Window B UITouch View C UIEvent - (NSSet *)touchesForWindow:(UIWindow *)window; EEC492/693/793 - iPhone Application Development
Window A UITouch UIEvent View A UITouch View B UITouch Window B UITouch View C UIEvent - (NSSet *)touchesForView:(UIView *)view; EEC492/693/793 - iPhone Application Development
Receiving Touches • UIResponder - (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; EEC492/693/793 - iPhone Application Development
UIResponder NSObject UIResponder UIViewController UIView UIApplication UIScrollView UIControl UILabel UIImageView UIControl UIButton UISlider UISwitch UITextField EEC492/693/793 - iPhone Application Development
Single & Multiple Touch Sequence Show Stanford Slides EEC492/693/793 - iPhone Application Development
The Touch Explore App - (void)updateLabelsFromTouches:(NSSet *)touches { NSUInteger numTaps = [[touches anyObject] tapCount]; NSString *tapsMessage = [[NSString alloc] initWithFormat:@"%d taps detected", numTaps]; tapsLabel.text = tapsMessage; [tapsMessage release]; NSUInteger numTouches = [touches count]; NSString *touchMsg = [[NSString alloc] initWithFormat: @"%d touches detected", numTouches]; touchesLabel.text = touchMsg; [touchMsg release]; } - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { messageLabel.text = @"Touches Began"; [self updateLabelsFromTouches:touches]; } - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {…} - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {…} - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event{…} EEC492/693/793 - iPhone Application Development
The Swipes App - (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) { label.text = @"Horizontal swipe detected"; [self performSelector:@selector(eraseText) withObject:nil afterDelay:2]; } else if (deltaY >= kMinimumGestureLength && deltaX <= kMaximumVariance){ label.text = @"Vertical swipe detected"; [self performSelector:@selector(eraseText) withObject:nil afterDelay:2]; } } EEC492/693/793 - iPhone Application Development
The Swipes App: Detect Multiple Swipes • When touchesBegan:withEvent: gets notified that a gesture has begun, we save one finger’s position • When we check for swipes, we loop through all the touches provided to the touchesMoved:withEvent: method, comparing each one to the saved point • If the user did a multiple-finger swipe, when comparing to the saved point, at least one of the touches we get in that method will indicate a swipe • If we find either a horizontal or vertical swipe, we loop through the touches again and make sure that every finger is at least the minimum distance away from the first finger’s horizontal or vertical position, depending on the type of swipe EEC492/693/793 - iPhone Application Development
The TapTaps App: Detecting Multiple Taps • If the user did a triple tap, there will be three separate notifications: • Single tap • Double tap • Triple tap • How can we handle the triple tap properly? • [self performSelector:@selector(singleTap) withObject:nil afterDelay:.4]; • [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(singleTap) object:nil]; EEC492/693/793 - iPhone Application Development
The PinchMe App - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { if ([touches count] == 2) { NSArray *twoTouches = [touches allObjects]; UITouch *first = [twoTouches objectAtIndex:0]; UITouch *second = [twoTouches objectAtIndex:1]; CGFloat currentDistance = distanceBetweenPoints( [first locationInView:self.view], [second locationInView:self.view]); if (initialDistance == 0) initialDistance = currentDistance; else if (currentDistance - initialDistance > kMinimumPinchDelta) { label.text = @"Outward Pinch"; [self performSelector:@selector(eraseLabel) withObject:nil afterDelay:1.6f]; } else if (initialDistance - currentDistance > kMinimumPinchDelta) { label.text = @"Inward Pinch"; [self performSelector:@selector(eraseLabel) withObject:nil afterDelay:1.6f]; } } } You need CGPointUtils.h and CGPointUtils.c EEC492/693/793 - iPhone Application Development
The CheckPlease App - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *touch = [touches anyObject]; CGPoint previousPoint = [touch previousLocationInView:self.view]; CGPoint currentPoint = [touch locationInView:self.view]; CGFloat angle = angleBetweenLines(lastPreviousPoint, lastCurrentPoint, previousPoint, currentPoint); if (angle >= kMinimumCheckMarkAngle&& angle <= kMaximumCheckMarkAngle && lineLengthSoFar > kMinimumCheckMarkLength) { label.text = @"Checkmark"; [self performSelector:@selector(eraseLabel) withObject:nil afterDelay:1.6]; } lineLengthSoFar += distanceBetweenPoints(previousPoint, currentPoint); lastPreviousPoint = previousPoint; lastCurrentPoint = currentPoint; } You need CGPointUtils.h and CGPointUtils.c EEC492/693/793 - iPhone Application Development