首先UIGestureRecognizer这个类包括7个子类 也就是7个手势
UITapGestureRecognier 轻敲手势
UIPinchGestureRecognier 捏合手势
UIRotationGestureRecognier 旋转手势
UISwipeGestureRecognier 侧滑手势(快速移动)
UIPanGestureRecognier 拖拽手势(慢速移动)
UIScreenEdgePanGestureRecognier 屏幕边缘拖拽手势
它是检测屏幕边缘的pan手势的。系统在某些controller转场的时候会使用这个手势。你也可以使用这个手势做其他的事情
UILongPressGestureRecgonier 长按手势
我以长按手势来介绍UIGestureRecognizer这个类 一下这些属性或者方法都是UIGestureRecognizer的,子类直接调用父类的
先创建个控件 对这个控件添加长按手势
UIImageView *imageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"Pikachu"]];
imageView.frame = CGRectMake(100, 100, 100, 100);
imageView.userInteractionEnabled = YES;
_imageView = imageView;
[self.view addSubview:imageView];
创建7种手势的时候 都是调用的父类UIGestureRecognizer的- (instancetype)initWithTarget:(id)target action:(SEL)action这个方法
target 一般都是self action就是触发这个手势后进的方法
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(longPress:)];
[self.imageView addGestureRecognizer:longPress];
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc]init];
[longPress addTarget:self action:@selector(longPress:)];
[self.imageView addGestureRecognizer:longPress];
设置代理 实现代理的方法
longPress.delegate = self;
默认是yes no的话 手势识别器将接收不到触摸
longPress.enabled = YES;
默认是yes 使得touchesCancelled:withEvent和pressesCancelled:withEvent这个两个方法在调用之前把所有的触摸和按压作为手势的一部分立刻传过去
longPress.cancelsTouchesInView = YES;
默认是no 在这个手势识别失败之前 使的所有的触摸和按压事件都被传递到那个view
yes的话 会阻止事件传递给那个view
longPress.delaysTouchesBegan = NO;
默认是yes 在这个手势识别失败之前 使的所有的触摸和按压事件都被传递到那个view
这样来保证这个手势上的触摸和按压事件都会取消
longPress.delaysTouchesEnded = YES;
这两个属性具体不知道啥意思
Array of UITouchType's as NSNumbers and Array of UIPressTypes as NSNumbers
longPress.allowedPressTypes = @[@(2)];
longPress.allowedTouchTypes = @[@(1)];
这个方法就是和其他手势建立一种依赖关系
拿这个tap为例 若实现了这个方法 当tap转换到UIGestureRecognizerStateFailed时候 这个longPress的reciever就会转换到他的正常状态
当这个tap转换到UIGestureRecognizerStateBegan和UIGestureRecognizerStateRecognized状态时候 这个reciever会转换到UIGestureRecognizerStateFailed
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]init];
[longPress requireGestureRecognizerToFail:tap];
longPress.view是 那个控件添加的这个手势 我们可以在changed里面做一下对这个view的操作
两个地址 是一样的 肯定是一样的
NSLog(@"self.imageView %p",self.imageView);
NSLog(@"longPress.view %p",longPress.view);
移除target 和 action 添加后 长按手势就不起作用了
[longPress removeTarget:self action:@selector(longPress:)];
//在这个方法里面 写UIGestureRecognizer其他的属性
-(void)longPress:(UILongPressGestureRecognizer *)longPress{
流程是possible->began->changed->cancell
或者是possible->began->changed->end
这个方法 第一个参数只是为了取到touch中特定的手势 UITouch中有一个私有类的数组包含这个手势
下表 就是取到响应的手势,view也是相应手势的view 来返回这个手指移动的point的
CGPoint point2 = [longPress locationOfTouch:0 inView:longPress.view];
这个point1指的是用户触发这个手势方法之后手指移动的point,相对于这个view来说的
这个point1和point2我的这个例子 是一样的,
CGPoint point1 = [longPress locationInView:longPress.view];
这个numberOfTouches指得是触发这个手势方法的手指个数
NSLog(@"numberOfTouches %lu",(unsigned long)longPress.numberOfTouches);
state 是手势的各种状态
if (longPress.state == UIGestureRecognizerStatePossible) {
识别器在未识别出它的手势,但可能会接收到触摸时处于这个状态。这是默认状态
NSLog(@"possible");
}else if (longPress.state == UIGestureRecognizerStateBegan){
识别器接收到触摸并识别出是它的手势时处于这个状态。响应方法将在下个循环步骤中被调用
NSLog(@"began");
}else if (longPress.state == UIGestureRecognizerStateChanged){
手势在识别过程中一直被调用直到fail end 或者cancell为止
NSLog(@"changed");
}else if (longPress.state == UIGestureRecognizerStateEnded){
识别器在识别到作为当前手势结束信号的触摸时处于这个状态。响应方法将在下个循环步骤中被调用 并且 识别器将重置为possible状态。
NSLog(@"end");
}else if (longPress.state == UIGestureRecognizerStateCancelled){
识别器处于取消状态.响应方法将在下个循环步骤中被调用 并且 识别器将重置为possible状态。
NSLog(@"cancelled");
}else if (longPress.state == UIGestureRecognizerStateFailed){
识别器接收到不能识别为它的手势的一系列触摸。响应方法不会被调用 并且 识别器将重置为possible状态
NSLog(@"failed");
}else if (longPress.state == UIGestureRecognizerStateRecognized){
识别器已识别到它的手势。响应方法将在下个循环步骤中被调用 并且 识别器将重置为possible状态
NSLog(@"recognized");
}else{}
#pragma mark - UIGestureRecognizerDelegate
-(BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{
yes的话 默认是possible到began
no的话 默认是possible到fail
return YES;
}
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
yes的话 意味着这个长按手势可以和其他手势同时被触发
no的话 意味着不可以和其他手势同时被触发 默认是no
但是 no的话不能保证一定不可以和其他手势同时触发 因为其他手势的代理方法可以设置为yes
return NO;
}
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRequireFailureOfGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
yes的话 在这个手势和其他手势之间创建动态的失败需求
yes 保证会创建这个动态失败需求 no不能保证,因为在其他手势的代理方法中可能return 的是yes
return YES;
}
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
这个还不知道什么意思呢
return YES;
}
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{
no的话 在touchBegan方法调用之前 会阻止手势识别这个触摸
return YES;
}
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceivePress:(UIPress *)press{
no的话pressesBegan方法调用之前 会阻止手势识别这个触摸
return YES;
}
以上都是子类调用 UIGestureRecognizer这个父类的方法