@fiy-fish
2017-03-24T22:27:03.000000Z
字数 5010
阅读 1283
工作日志
view上有多个手势
使用view.gestureRecognizers 来取所所有view上的手势
默认情况下,同一个view的多种手势的触发是无序的,但是可以通过API来实现有序控制;
● 可以指定一个手势在另外一个手势之前进行touch事件的解析
● 两个手势可以在同一时间内操作
● 不让一个手势进行touch事件的解析
两个手势的识别顺序
比如view有两个手势,轻扫手势和轻捏手势,这两个手势很像,我们要手动忽略其中一个可以使用下面的方法
iOS7 之前, requireGestureRecognizerToFail:
iOS7 之后,
gestureRecognizer:shouldRequireFailureOfGestureRecognizer:
gestureRecognizer:shouldBeRequiredToFailByGestureRecognizer:
如下面的代码:
UIScreenEdgePanGestureRecognizer *myScreenEdgePanGestureRecognizer;
...
myScreenEdgePanGestureRecognizer = [[UIScreenEdgePanGestureRecognizer alloc] initWithTarget:self action:@selector(handleScreenEdgePan:)];
myScreenEdgePanGestureRecognizer.delegate = self;
// Configure the gesture recognizer and attach it to the view.
...
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
BOOL result = NO;
if ((gestureRecognizer == myScreenEdgePanGestureRecognizer) && [[otherGestureRecognizer view] isDescendantOfView:[gestureRecognizer view]]) {
result = YES;
}
return result;
}
阻止手势识别:
1.两个代理方法:
2.重写view方法: gestureRecognizerShouldBegin: 来实现上面同样的效果
多个手势同时识别
多个手势中明确响应其中一个
重写方法
手势和其他control控件冲突(手势加在 这些控件的父视图上)
iOS6.0之后,当手势和Control控件重叠之后,手势事件将不响应。具体事例如下
拖动手势 和 UISwitch (和switch 方向平行)
注意:如果手势是直接加到这些control控件之上 ,则手势事件截取触摸事件。
控制屏幕触摸的传递
一般情况下,事件先传递给手势识别,再传递给绑定手势的view。
事件传递过程
APP --->Wiondow --->Gester recognize
--->View
touch的began,move状态可以同时传递给手势和view,但是end状态先传递给手势,手势会根据touch的状态来判断是否识别手势,如果识别则相应touch事件,这时候会把touch的cansel状态传递给view。view不传递该touch 事件。如果手势没有识别这个touch事件,则touch的end状态传递给view,view把这个touch事件传递下去.
也就是说:如果手势识别了这个touch,则touch 不再传给view,之前传递给view的touch 状态现在变成 UITouchPhaseCancelled
如果手势没有识别这个touch,则touch 传递给view
触摸传递对view的影响
一般情况下,手势在touch的end状态时可以决定是否识别该touch,所有touch之前的状态 如 begin ,move状态都会传递给view,当touch 的end状态时被手势识别出来后,touch传递给view cansel状态,取消之前所有传给view的touch ,如果没有识别出来,则把touch 的end状态传递给view。
delaysTouchesBegan 默认NO, 当设为YES时,事件将会延迟传递给view,手势如果识别touch,会拦截touch 的所有状态(begin,move,end)
手势如果没有识别touh,这个时候才会把touch传递给view
比如UIScrollView 就设置了 delaysContentTouches=YES
这个时候 view会变得反应迟钝
delaysTouchesEnded 默认YES
为YES时,手势识别了touch,则touch的end状态不会传递给view,如果手势没有识别touch,则把touch的end状态传递给view。
当我们设置 delaysTouchesEnded=NO时,手势和view同步分析touch 没有先后之分。
//导入AVFoundation框架
#import <AVFoundation/AVFoundation.h>
第二步:
//签协议,我们会在协议方法里获取到扫描结果
@interface ViewController ()<AVCaptureMetadataOutputObjectsDelegate>
第三步:
@property(nonatomic, strong)AVCaptureSession *session;//输入输出的中间桥梁
第四步:
#pragma mark -- 开始扫描
- (void)startScanWithSize:(CGFloat)sizeValue
{
//获取摄像设备
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
//创建输入流
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];
//判断输入流是否可用
if (input) {
//创建输出流
AVCaptureMetadataOutput * output = [[AVCaptureMetadataOutput alloc]init];
//设置代理,在主线程里刷新,注意此时self需要签AVCaptureMetadataOutputObjectsDelegate协议
[output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
//初始化连接对象
self.session = [[AVCaptureSession alloc]init];
//高质量采集率
[_session setSessionPreset:AVCaptureSessionPresetHigh];
[_session addInput:input];
[_session addOutput:output];
//设置扫码支持的编码格式(如下设置条形码和二维码兼容)
output.metadataObjectTypes = @[AVMetadataObjectTypeQRCode,AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode128Code];
//扫描区域大小的设置:(这部分也可以自定义,显示自己想要的布局)
AVCaptureVideoPreviewLayer *layer = [AVCaptureVideoPreviewLayer layerWithSession:_session];
layer.videoGravity = AVLayerVideoGravityResizeAspectFill;
//设置为宽高为200的正方形区域相对于屏幕居中
layer.frame = CGRectMake((self.view.bounds.size.width - sizeValue) / 2.0, (self.view.bounds.size.height - sizeValue) / 2.0, sizeValue, sizeValue);
[self.view.layer insertSublayer:layer atIndex:0];
//开始捕获图像:
[_session startRunning];
}
}
第五步:
#pragma mark -- 调用扫描方法
- (void)viewDidLoad {
[super viewDidLoad];
//300为正方形扫描区域边长
[self startScanWithSize:300];
}
第六步:
#pragma mark - 扫面结果在这个代理方法里获取到
-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection{
if (metadataObjects.count>0) {
//获取到信息后停止扫描:
[_session stopRunning];
AVMetadataMachineReadableCodeObject *metaDataObject = [metadataObjects objectAtIndex:0];
//输出扫描字符串:
NSLog(@"%@", metaDataObject.stringValue);
//移除扫描视图:
AVCaptureVideoPreviewLayer *layer = (AVCaptureVideoPreviewLayer *)[[self.view.layer sublayers] objectAtIndex:0];
[layer removeFromSuperlayer];
}
}