@fiy-fish
2017-03-24T14:27:03.000000Z
字数 5010
阅读 1473
工作日志
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];}}