UIGestureRecognizer
利用UIGestureRecognizer,能轻松识别用户在某个view上面做的一些常见手势
UIGestureRecognizer是一个抽象类,定义了所有手势的基本行为,使用它的子类才能处理具体的手势
UITapGestureRecognizer (敲击)UIPinchGestureRecognizer (捏合,用于缩放)UIPanGestureRecognizer (拖拽)UISwipeGestureRecognizer (轻扫)UIRotationGestureRecognizer (旋转)UILongPressGestureRecognizer (长按)
使用方法 创建点按手势 UITapGestureRecognizer *gesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector (tap:)];self .imageView.userInteractionEnabled = YES ;[self .imageView addGestureRecognizer:gesture];
响应手势事件,可以在里面进行形变 - (void )tap:(UITapGestureRecognizer *)tap { NSLog (@"%s" ,__func__); self .imageView.transform = CGAffineTransformRotate (self .imageView.transform, M_PI_4); }
手势的状态 typedef NS_ENUM (NSInteger , UIGestureRecognizerState ) { UIGestureRecognizerStatePossible , UIGestureRecognizerStateBegan , UIGestureRecognizerStateChanged , UIGestureRecognizerStateEnded , UIGestureRecognizerStateCancelled , UIGestureRecognizerStateFailed , UIGestureRecognizerStateRecognized = UIGestureRecognizerStateEnded };
手势的一些代理方法 #pragma mark - 手势代理方法 - (BOOL )gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer { return YES ; } - (BOOL )gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { return YES ; } - (BOOL )gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch { return YES ; }
逐个实现每个手势 1、点按 UITapGestureRecognizer #pragma mark - 各种手势 - (void )tapImage { UITapGestureRecognizer *gestur = [[UITapGestureRecognizeralloc ] initWithTarget:selfaction:@selector (tap:)]; gestur.delegate = self ; gestur.numberOfTapsRequired = 2 ; [self .imageView addGestureRecognizer:gestur]; } - (void )tap:(UITapGestureRecognizer *)tap { if (tap.numberOfTapsRequired == 2 ) { self .imageView.image = [UIImage imageNamed:@"qianbao" ]; } } ``` ### 2、捏合 可以使用两个手指进行缩放 UIPinchGestureRecognizer ```objc - (void )pinchImage { UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizeralloc ] initWithTarget:selfaction:@selector (pinch:)]; [self .imageViewaddGestureRecognizer:pinch]; } - (void )pinch:(UIPinchGestureRecognizer *)pinch { self .imageView.transform = CGAffineTransformScale (self .imageView.transform, pinch.scale,pinch.scale); pinch.scale = 1 ; } ``` ### 3、长按 UILongPressGestureRecognizer ```objc - (void )longPressImage { UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizeralloc ] initWithTarget:selfaction:@selector (longPress:)]; [self .imageView addGestureRecognizer:longPress]; } - (void )longPress:(UILongPressGestureRecognizer *)longP { if (longP.state == UIGestureRecognizerStateBegan ) { self .imageView.transform = CGAffineTransformRotate (self .imageView.transform, M_PI); } }
4、清扫 轻轻向某个方向滑动 - (void )swipeImage { UISwipeGestureRecognizer *swipe = [[UISwipeGestureRecognizeralloc ] initWithTarget:selfaction:@selector (swipe:)]; [self .imageViewaddGestureRecognizer:swipe]; UISwipeGestureRecognizer *swipeUp = [[UISwipeGestureRecognizeralloc ] initWithTarget:selfaction:@selector (swipe:)]; swipeUp.direction = UISwipeGestureRecognizerDirectionUp ; [self .imageView addGestureRecognizer:swipeUp]; } - (void )swipe:(UISwipeGestureRecognizer *)swipe { NSLog (@"%s\n%ld" ,__func__,swipe.direction); }
5、旋转 UIRotationGestureRecognizer - (void )rotateImage { UIRotationGestureRecognizer *rotate = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector (rotate:)]; [self .imageView addGestureRecognizer:rotate]; } - (void )rotate:(UIRotationGestureRecognizer *)rotate { self .imageView.transform = CGAffineTransformRotate (self .imageView.transform, rotate.rotation); rotate.rotation = 0 ; }
6、拖拽 UIPanGestureRecognizer - (void )panImage { UIPanGestureRecognizer *pan = [[UIPanGestureRecognizeralloc ] initWithTarget:selfaction:@selector (pan:)]; [self .imageViewaddGestureRecognizer:pan]; } - (void )pan:(UIPanGestureRecognizer *)pan { CGPoint curP = [pan translationInView:self .imageView]; self .imageView.transform = CGAffineTransformTranslate (self .imageView.transform, curP.x, curP.y); [pan setTranslation:CGPointZeroinView :self .imageView]; } ``` ### 7、在视图加载时进行调用即可 ```objc - (void )viewDidLoad { [super viewDidLoad]; self .imageView.userInteractionEnabled = YES ; [self tapImage]; [selflongPressImage]; [self swipeImage]; [self rotateImage]; [self pinchImage]; }
简单效果如下
手势使用例子-抽屉效果
1、需要三个视图,一个主视图,两个底部视图 @property (nonatomic ,weak ) UIView *mainView;@property (nonatomic ,weak ) UIView *leftView;@property (nonatomic ,weak ) UIView *rightView;
2、初始化界面 - (void )initUI { UIView *left = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds]; self .leftView = left; self .leftView.backgroundColor = [UIColorblueColor ]; [self .view addSubview:self .leftView]; UIView *right = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds]; self .rightView = right; self .rightView.backgroundColor = [UIColorgreenColor ]; [self .view addSubview:self .rightView]; UIView *main = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds]; self .mainView = main; self .mainView.backgroundColor = [UIColorredColor ]; [self .view addSubview:self .mainView]; }
3、添加手势 - (void )viewDidLoad { [super viewDidLoad]; [self initUI]; UIPanGestureRecognizer *pan = [[UIPanGestureRecognizeralloc ] initWithTarget:selfaction:@selector (pan:)]; [self .view addGestureRecognizer:pan]; }
4、手势监听方法 #define kLeft -250 #define kRight 275 - (void )pan:(UIPanGestureRecognizer *)pan { CGPoint curP = [pan translationInView:self .view]; self .mainView.frame = [self frameWithOffsetX:curP.x]; [self observeValueForKeyPath:nil ofObject:nil change:nil context:nil ]; [pan setTranslation:CGPointZero inView:self .view]; if (pan.state == UIGestureRecognizerStateEnded ) { CGFloat target = 0 ; if (self .mainView.frame.origin.x > kWidth * 0.5 ) { target = kRight; } else if (CGRectGetMaxX (self .mainView.frame) < kWidth * 0.5 ) { target = kLeft; } CGFloat offsetX = target - self .mainView.frame.origin.x ; [UIView animateWithDuration:0.25 animations:^{ if (target == 0 ) { self .mainView.frame = self .view.bounds; } else { self .mainView.frame = [self frameWithOffsetX:offsetX]; } }]; } }
5、每次滑动时都要判断要显示的底部视图,显示left还是right,根据x值就可以判断 - (void )observeValueForKeyPath:(NSString *)keyPath ofObject:(id )object change:(NSDictionary *)change context:(void *)context { if (self .mainView.frame.origin.x > 0 ) { self .rightView.hidden = YES ; self .leftView.hidden = NO ; } else { self .rightView.hidden = NO ; self .leftView.hidden = YES ; } }
6、每次滑动都要随时判断frame的状态,在方法 frameWithOffsetX 中进行判断 #define kWidth 80 // 距离顶部最大距离 - (CGRect )frameWithOffsetX:(CGFloat )offsetX { CGRect frame = self .mainView.frame; frame.origin.x += offsetX; CGFloat screenW = [UIScreenmainScreen ].bounds.size.width; CGFloat screenH = [UIScreenmainScreen ].bounds.size.height; CGFloat offsetY = offsetX * kWidth / screenW; CGFloat preH = frame.size.height; CGFloat preW = frame.size.width; CGFloat curH = preH - 2 * offsetY; if (frame.origin.x < 0 ) { curH = preH + 2 * offsetY; } CGFloat scale = curH / preH; CGFloat curW = preW * scale; frame.origin.y = (screenH - curH) / 2 ; frame.size.height = curH; frame.size.width = curW; return frame; }
7、自动提示宏 - 在使用KVO对某个属性进行监听时,如果参数直接传入字符串,很有可能写错。可以使用自动提示宏来自动提示要监视的属性。
[self .mainViewaddObserver:selfforKeyPath:keyPath(self .mainView, frame) options:NSKeyValueObservingOptionNewcontext :nil ]; [self .mainView addObserver:self forKeyPath:@“frame”options:NSKeyValueObservingOptionNew context:nil ]; 在方法 observeValueForKeyPath 中对属性改变进行监听。
8、宏的书写规则 #define keyPath(obj,keyPath) @(((void)obj.keyPath,#keyPath))