UIGestureRecognizer 是一个具体手势的基类,提供了较为简单的手势实现方式
The concrete subclasses of
UIGestureRecognizer
are the following:
-
UITapGestureRecognizer
-
UIPinchGestureRecognizer
-
UIRotationGestureRecognizer
-
UISwipeGestureRecognizer
-
UIPanGestureRecognizer
-
UILongPressGestureRecognizer
一个gesture recognizer是针对一个特定的view的(包含其subview),用UIView的方法addGestureRecognize:去关联一个view
一个gesture recognizer是不参与UIView的事件响应链的
各个手势使用时的代码:
UITapGestureRecognizer
[cpp] view plain copy
- - (void)viewDidLoad
- {
- [super viewDidLoad];
- // Do any additional setup after loading the view from its nib.
- UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture:)];
- if (![tapGesture respondsToSelector:@selector(locationInView:)]) {
- [tapGesture release];
- tapGesture = nil;
- }else {
- tapGesture.delegate = self;
- tapGesture.numberOfTapsRequired = 1; // The default value is 1.
- tapGesture.numberOfTouchesRequired = 1; // The default value is 1.
- [self.view addGestureRecognizer:tapGesture];
- }
- }
[cpp] view plain copy
- - (void)handleGesture:(UIGestureRecognizer *)gestureRecognizer
- {
- UIView *view = [gestureRecognizer view]; // 这个view是手势所属的view,也就是增加手势的那个view
- switch (gestureRecognizer.state) {
- case UIGestureRecognizerStateEnded:{ // UIGestureRecognizerStateRecognized = UIGestureRecognizerStateEnded // 正常情况下只响应这个消息
- NSLog(@"======UIGestureRecognizerStateEnded || UIGestureRecognizerStateRecognized");
- break;
- }
- case UIGestureRecognizerStateFailed:{ //
- NSLog(@"======UIGestureRecognizerStateFailed");
- break;
- }
- case UIGestureRecognizerStatePossible:{ //
- NSLog(@"======UIGestureRecognizerStatePossible");
- break;
- }
- default:{
- NSLog(@"======Unknow gestureRecognizer");
- break;
- }
- }
- }
- // 询问一个手势接收者是否应该开始解释执行一个触摸接收事件
- - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{
- // CGPoint currentPoint = [gestureRecognizer locationInView:self.view];
- // if (CGRectContainsPoint(CGRectMake(0, 0, 100, 100), currentPoint) ) {
- // return YES;
- // }
- //
- // return NO;
- return YES;
- }
- // 询问delegate,两个手势是否同时接收消息,返回YES同事接收。返回NO,不同是接收(如果另外一个手势返回YES,则并不能保证不同时接收消息)the default implementation returns NO。
- // 这个函数一般在一个手势接收者要阻止另外一个手势接收自己的消息的时候调用
- - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
- return NO;
- }
- // 询问delegate是否允许手势接收者接收一个touch对象
- // 返回YES,则允许对这个touch对象审核,NO,则不允许。
- // 这个方法在touchesBegan:withEvent:之前调用,为一个新的touch对象进行调用
- - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{
- return YES;
- }
UIPinchGestureRecognizer
[cpp] view plain copy
- - (void)viewDidLoad
- {
- [super viewDidLoad];
- // Do any additional setup after loading the view from its nib.
- UIPinchGestureRecognizer *pinchGesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture:)];
- if (![pinchGesture respondsToSelector:@selector(locationInView:)]) {
- [pinchGesture release];
- pinchGesture = nil;
- }else {
- pinchGesture.delegate = self;
- [self.view addGestureRecognizer: pinchGesture];
- }
- }
- - (void)handleGesture:(UIPinchGestureRecognizer *)gestureRecognizer
- {
- UIView *view = [gestureRecognizer view]; // 这个view是手势所属的view,也就是增加手势的那个view
- CGFloat scale = gestureRecognizer.scale;
- NSLog(@"======scale: %f", scale);
- CGFloat velocity = gestureRecognizer.velocity;
- NSLog(@"======scvelocityale: %f", velocity);
- switch (gestureRecognizer.state) {
- case UIGestureRecognizerStateEnded:{ // UIGestureRecognizerStateRecognized = UIGestureRecognizerStateEnded
- NSLog(@"======UIGestureRecognizerStateEnded || UIGestureRecognizerStateRecognized");
- break;
- }
- case UIGestureRecognizerStateBegan:{ //
- NSLog(@"======UIGestureRecognizerStateBegan");
- break;
- }
- case UIGestureRecognizerStateChanged:{ //
- NSLog(@"======UIGestureRecognizerStateChanged");
- gestureRecognizer.view.transform = CGAffineTransformScale(gestureRecognizer.view.transform, gestureRecognizer.scale, gestureRecognizer.scale);
- gestureRecognizer.scale = 1; // 重置,很重要!!!
- break;
- }
- case UIGestureRecognizerStateCancelled:{ //
- NSLog(@"======UIGestureRecognizerStateCancelled");
- break;
- }
- case UIGestureRecognizerStateFailed:{ //
- NSLog(@"======UIGestureRecognizerStateFailed");
- break;
- }
- case UIGestureRecognizerStatePossible:{ //
- NSLog(@"======UIGestureRecognizerStatePossible");
- break;
- }
- default:{
- NSLog(@"======Unknow gestureRecognizer");
- break;
- }
- }
- }
UIRotationGestureRecognizer
[cpp] view plain copy
- - (void)viewDidLoad
- {
- [super viewDidLoad];
- // Do any additional setup after loading the view from its nib.
- UIRotationGestureRecognizer *rotationGesture = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture:)];
- if (![rotationGesture respondsToSelector:@selector(locationInView:)]) {
- [rotationGesture release];
- rotationGesture = nil;
- }else {
- rotationGesture.delegate = self;
- [self.view addGestureRecognizer:rotationGesture];
- }
- }
- - (void)handleGesture:(UIRotationGestureRecognizer *)gestureRecognizer
- {
- UIView *view = [gestureRecognizer view]; // 这个view是手势所属的view,也就是增加手势的那个view
- CGFloat rotation = gestureRecognizer.rotation;
- NSLog(@"===rotation: %f", rotation);
- CGFloat velocity = gestureRecognizer.velocity;
- NSLog(@"======velocity: %f", velocity);
- switch (gestureRecognizer.state) {
- case UIGestureRecognizerStateEnded:{ // UIGestureRecognizerStateRecognized = UIGestureRecognizerStateEnded
- NSLog(@"======UIGestureRecognizerStateEnded || UIGestureRecognizerStateRecognized");
- break;
- }
- case UIGestureRecognizerStateBegan:{ //
- NSLog(@"======UIGestureRecognizerStateBegan");
- break;
- }
- case UIGestureRecognizerStateChanged:{ //
- NSLog(@"======UIGestureRecognizerStateChanged");
- gestureRecognizer.view.transform = CGAffineTransformRotate(gestureRecognizer.view.transform, gestureRecognizer.rotation);
- gestureRecognizer.rotation = 0; // 重置 这个相当重要!!!
- break;
- }
- case UIGestureRecognizerStateCancelled:{ //
- NSLog(@"======UIGestureRecognizerStateCancelled");
- break;
- }
- case UIGestureRecognizerStateFailed:{ //
- NSLog(@"======UIGestureRecognizerStateFailed");
- break;
- }
- case UIGestureRecognizerStatePossible:{ //
- NSLog(@"======UIGestureRecognizerStatePossible");
- break;
- }
- default:{
- NSLog(@"======Unknow gestureRecognizer");
- break;
- }
- }
- }
UISwipeGestureRecognizer
[cpp] view plain copy
- - (void)viewDidLoad
- {
- [super viewDidLoad];
- // Do any additional setup after loading the view from its nib.
- // right
- UISwipeGestureRecognizer *swipeGestureRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture:)];
- if (![swipeGestureRight respondsToSelector:@selector(locationInView:)]) {
- [swipeGestureRight release];
- swipeGestureRight = nil;
- }else {
- swipeGestureRight.delegate = self;
- swipeGestureRight.numberOfTouchesRequired = 1;// 手指个数 The default value is 1.
- swipeGestureRight.direction = UISwipeGestureRecognizerDirectionRight;// 同一个手势只能指定一个方向,不能同时指定多个方向,要指定多个方向 必须用多个手势
- [self.view addGestureRecognizer:swipeGestureRight];
- }
- // left
- UISwipeGestureRecognizer *swipeGestureLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture:)];
- if (![swipeGestureLeft respondsToSelector:@selector(locationInView:)]) {
- [swipeGestureLeft release];
- swipeGestureLeft = nil;
- }else {
- swipeGestureLeft.delegate = self;
- swipeGestureLeft.numberOfTouchesRequired = 1;// 手指个数 The default value is 1.
- swipeGestureLeft.direction = UISwipeGestureRecognizerDirectionLeft;// 同一个手势只能指定一个方向,不能同时指定多个方向,要指定多个方向 必须用多个手势
- [self.view addGestureRecognizer:swipeGestureLeft];
- }
- // Up
- UISwipeGestureRecognizer *swipeGestureUp = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture:)];
- if (![swipeGestureUp respondsToSelector:@selector(locationInView:)]) {
- [swipeGestureUp release];
- swipeGestureUp = nil;
- }else {
- swipeGestureUp.delegate = self;
- swipeGestureUp.numberOfTouchesRequired = 1;// 手指个数 The default value is 1.
- swipeGestureUp.direction = UISwipeGestureRecognizerDirectionUp;// 同一个手势只能指定一个方向,不能同时指定多个方向,要指定多个方向 必须用多个手势
- [self.view addGestureRecognizer:swipeGestureUp];
- }
- // Down
- UISwipeGestureRecognizer *swipeGestureDown = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture:)];
- if (![swipeGestureDown respondsToSelector:@selector(locationInView:)]) {
- [swipeGestureDown release];
- swipeGestureDown = nil;
- }else {
- swipeGestureDown.delegate = self;
- swipeGestureDown.numberOfTouchesRequired = 1;// 手指个数 The default value is 1.
- swipeGestureDown.direction = UISwipeGestureRecognizerDirectionDown;// 同一个手势只能指定一个方向,不能同时指定多个方向,要指定多个方向 必须用多个手势
- [self.view addGestureRecognizer:swipeGestureDown];
- }
- }
- - (void)handleGesture:(UISwipeGestureRecognizer *)gestureRecognizer
- {
- UIView *view = [gestureRecognizer view]; // 这个view是手势所属的view,也就是增加手势的那个view
- UISwipeGestureRecognizerDirection direction = gestureRecognizer.direction;
- switch (direction) {
- case UISwipeGestureRecognizerDirectionRight:
- {
- NSLog(@"direction==UISwipeGestureRecognizerDirectionRight");
- break;
- }
- case UISwipeGestureRecognizerDirectionLeft:
- {
- NSLog(@"direction==UISwipeGestureRecognizerDirectionLeft");
- break;
- }
- case UISwipeGestureRecognizerDirectionUp:
- {
- NSLog(@"direction==UISwipeGestureRecognizerDirectionUp");
- break;
- }
- case UISwipeGestureRecognizerDirectionDown:
- {
- NSLog(@"direction==UISwipeGestureRecognizerDirectionDown");
- break;
- }
- default:
- break;
- }
- switch (gestureRecognizer.state) {
- case UIGestureRecognizerStateEnded:{ // UIGestureRecognizerStateRecognized = UIGestureRecognizerStateEnded
- NSLog(@"======UIGestureRecognizerStateEnded || UIGestureRecognizerStateRecognized");
- break;
- }
- default:{
- NSLog(@"======Unknow gestureRecognizer");
- break;
- }
- }
- }
UIPanGestureRecognizer
[cpp] view plain copy
- - (void)viewDidLoad
- {
- [super viewDidLoad];
- // Do any additional setup after loading the view from its nib.
- UIView *view = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 100, 100)];
- view.backgroundColor = [UIColor blueColor];
- [self.view addSubview:view];
- UIPanGestureRecognizer *panPressGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture:)];
- if (![panPressGesture respondsToSelector:@selector(locationInView:)]) {
- [panPressGesture release];
- panPressGesture = nil;
- }else {
- panPressGesture.delegate = self;
- panPressGesture.maximumNumberOfTouches = NSUIntegerMax;// The default value is NSUIntegerMax.
- panPressGesture.minimumNumberOfTouches = 1;// The default value is 1.
- [view addGestureRecognizer:panPressGesture];
- }
- }
- // 拖拽手势
- - (void)handleGesture:(UIPanGestureRecognizer *)gestureRecognizer
- {
- UIView *view = [gestureRecognizer view]; // 这个view是手势所属的view,也就是增加手势的那个view
- switch (gestureRecognizer.state) {
- case UIGestureRecognizerStateBegan:{
- NSLog(@"======UIGestureRecognizerStateBegan");
- break;
- }
- case UIGestureRecognizerStateChanged:{
- NSLog(@"======UIGestureRecognizerStateChanged");
- CGPoint translation = [gestureRecognizer translationInView:self.view];
- view.center = CGPointMake(gestureRecognizer.view.center.x + translation.x, gestureRecognizer.view.center.y + translation.y);
- [gestureRecognizer setTranslation:CGPointMake(0, 0) inView:self.view];// 注意一旦你完成上述的移动,将translation重置为0十分重要。否则translation每次都会叠加,很快你的view就会移除屏幕!
- break;
- }
- case UIGestureRecognizerStateCancelled:{
- NSLog(@"======UIGestureRecognizerStateCancelled");
- break;
- }
- case UIGestureRecognizerStateFailed:{
- NSLog(@"======UIGestureRecognizerStateFailed");
- break;
- }
- case UIGestureRecognizerStatePossible:{
- NSLog(@"======UIGestureRecognizerStatePossible");
- break;
- }
- case UIGestureRecognizerStateEnded:{ // UIGestureRecognizerStateRecognized = UIGestureRecognizerStateEnded
- NSLog(@"======UIGestureRecognizerStateEnded || UIGestureRecognizerStateRecognized");
- CGPoint velocity = [gestureRecognizer velocityInView:self.view];// 分别得出x,y轴方向的速度向量长度(velocity代表按照当前速度,每秒可移动的像素个数,分xy轴两个方向)
- CGFloat magnitude = sqrtf((velocity.x * velocity.x) + (velocity.y * velocity.y));// 根据直角三角形的算法算出综合速度向量长度
- // 如果长度小于200,则减少基本速度,否则增加它。
- CGFloat slideMult = magnitude / 200;
- NSLog(@"magnitude: %f, slideMult: %f", magnitude, slideMult);
- float slideFactor = 0.1 * slideMult; // Increase for more of a slide
- // 基于速度和滑动因子计算终点
- CGPoint finalPoint = CGPointMake(view.center.x + (velocity.x * slideFactor),
- view.center.y + (velocity.y * slideFactor));
- // 确定终点在视图边界内
- finalPoint.x = MIN(MAX(finalPoint.x, 0), self.view.bounds.size.width);
- finalPoint.y = MIN(MAX(finalPoint.y, 0), self.view.bounds.size.height);
- [UIView animateWithDuration:slideFactor*2 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
- view.center = finalPoint;
- } completion:nil];
- break;
- }
- default:{
- NSLog(@"======Unknow gestureRecognizer");
- break;
- }
- }
- }
UILongPressGestureRecognizer
[cpp] view plain copy
- - (void)viewDidLoad
- {
- [super viewDidLoad];
- // Do any additional setup after loading the view from its nib.
- UILongPressGestureRecognizer *longPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture:)];
- if (![longPressGesture respondsToSelector:@selector(locationInView:)]) {
- [longPressGesture release];
- longPressGesture = nil;
- }else {
- longPressGesture.delegate = self;
- longPressGesture.numberOfTapsRequired = 0; // The default number of taps is 0.
- longPressGesture.minimumPressDuration = 0.1f; // The default duration is is 0.5 seconds.
- longPressGesture.numberOfTouchesRequired = 1; // The default number of fingers is 1.
- longPressGesture.allowableMovement = 10; // The default distance is 10 pixels.
- [self.view addGestureRecognizer:longPressGesture];
- }
- }
- - (void)handleGesture:(UIGestureRecognizer *)gestureRecognizer
- {
- UIView *view = [gestureRecognizer view]; // 这个view是手势所属的view,也就是增加手势的那个view
- switch (gestureRecognizer.state) {
- case UIGestureRecognizerStateEnded:{ // UIGestureRecognizerStateRecognized = UIGestureRecognizerStateEnded
- NSLog(@"======UIGestureRecognizerStateEnded || UIGestureRecognizerStateRecognized");
- break;
- }
- case UIGestureRecognizerStateBegan:{ //
- NSLog(@"======UIGestureRecognizerStateBegan");
- break;
- }
- case UIGestureRecognizerStateChanged:{ //
- NSLog(@"======UIGestureRecognizerStateChanged");
- break;
- }
- case UIGestureRecognizerStateCancelled:{ //
- NSLog(@"======UIGestureRecognizerStateCancelled");
- break;
- }
- case UIGestureRecognizerStateFailed:{ //
- NSLog(@"======UIGestureRecognizerStateFailed");
- break;
- }
- case UIGestureRecognizerStatePossible:{ //
- NSLog(@"======UIGestureRecognizerStatePossible");
- break;
- }
- default:{
- NSLog(@"======Unknow gestureRecognizer");
- break;
- }
- }
- }
- // 询问一个手势接收者是否应该开始解释执行一个触摸接收事件
- - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{
- CGPoint currentPoint = [gestureRecognizer locationInView:self.view];
- if (CGRectContainsPoint(CGRectMake(0, 0, 100, 100), currentPoint) ) {
- return YES;
- }
- return NO;
- }
- // 询问delegate,两个手势是否同时接收消息,返回YES同事接收。返回NO,不同是接收(如果另外一个手势返回YES,则并不能保证不同时接收消息)the default implementation returns NO。
- // 这个函数一般在一个手势接收者要阻止另外一个手势接收自己的消息的时候调用
- - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
- return NO;
- }
- // 询问delegate是否允许手势接收者接收一个touch对象
- // 返回YES,则允许对这个touch对象审核,NO,则不允许。
- // 这个方法在touchesBegan:withEvent:之前调用,为一个新的touch对象进行调用
- - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{
- return YES;
- }