iOS轻点、触摸和手势代码开发
一、响应者链
以UIResponder作为超类的任何类都是响应者。UIView和UIControl是UIReponder的子类,因此所有视图和所有控件都是响应者。
1、初始相应器
事件首先会传递给UIApplication对象,接下来会传递给应用程序的UIWindow,UIWindow会选择一个初始相应器来处理事件。初始响应器会选择下面的方式选择1、对于触摸事件,UIWindow会确定用户触摸的视图,然后将事件交给注册了这个视图的手势识别器或则注册视图层级更高的手势识别器。只要存在能处理事件的识别器,就不会再继续找了。如果没有的话,被触摸视图就是初始相应器,事件也会传递给它。
2、对于用户摇晃设备产生的或者是来自远程遥控设备事件,将会传递给第一响应器
如果初始响应器不处理时间,它会将事件传递给它的父视图(如果存在的话),或者传递给视图控制器(如果此视图是视图控制器的视图)。如果视图控制器不处理事件,它将沿着响应器链的层级继续传给父视图控制器(如果存在的话)。
如果在整个视图层级中都没与能处理事件的视图或控制器,事件就会被传递给应用程序的窗口。如果窗口不能处理事件,而应用委托是UIResponder的子类,UIApplication对象就会将其传递给应用程序委托。最后,如果应用委托不是UIResponder的子类,或者不处理这个事件,那么这个事件将会被丢弃。
4个手势通知方法
#pragmamark-TouchEventMethods //用户第一次触摸屏幕时被调用 -(void)touchesBegan:(NSSet<UITouch*>*)toucheswithEvent:(UIEvent*)event { } //当发生某些事件(如来电呼叫)导致手势中断时被调用 -(void)touchesCancelled:(NSSet<UITouch*>*)toucheswithEvent:(UIEvent*)event { } //当用户手指离开屏幕时被调用 -(void)touchesEnded:(NSSet<UITouch*>*)toucheswithEvent:(UIEvent*)event { } //当用户手指移动时触发 -(void)touchesMoved:(NSSet<UITouch*>*)toucheswithEvent:(UIEvent*)event { }
二、检测扫描事件
1、手动检测
// //ViewController.m //Swipes // //CreatedbyJierismon16/8/4. //Copyright©2016年Jierism.Allrightsreserved. // #import"ViewController.h" //设置检测范围 staticCGFloatconstkMinimmGestureLength=25; staticCGFloatconstkMaximmVariance=5; @interfaceViewController() @property(weak,nonatomic)IBOutletUILabel*label; @property(nonatomic)CGPointgestureStartPoint; @end @implementationViewController -(void)viewDidLoad{ [superviewDidLoad]; //Doanyadditionalsetupafterloadingtheview,typicallyfromanib. } -(void)didReceiveMemoryWarning{ [superdidReceiveMemoryWarning]; //Disposeofanyresourcesthatcanberecreated. } -(void)touchesBegan:(NSSet<UITouch*>*)toucheswithEvent:(UIEvent*)event { UITouch*touch=[touchesanyObject]; self.gestureStartPoint=[touchlocationInView:self.view]; } -(void)touchesMoved:(NSSet<UITouch*>*)toucheswithEvent:(UIEvent*)event { UITouch*touch=[touchesanyObject]; CGPointcurrentPosition=[touchlocationInView:self.view]; //返回一个float的绝对值 CGFloatdeltaX=fabsf(self.gestureStartPoint.x-currentPosition.x); CGFloatdeltaY=fabsf(self.gestureStartPoint.y-currentPosition.y); //获得两个增量后,判断用户在两个方向上移动过的距离,检测用户是否在一个方向上移动得足够远但在另一个方向移动得不够来形成轻扫动作 if(deltaX>=kMinimmGestureLength&&deltaY<=kMaximmVariance){ self.label.text=@"Horizontalswipedetected"; //2s后擦除文本 dispatch_after(dispatch_time(DISPATCH_TIME_NOW,(int64_t)(2*NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ self.label.text=@""; }); }elseif(deltaY>=kMinimmGestureLength&&deltaX<=kMaximmVariance){ self.label.text=@"Verticalswipedetected"; dispatch_after(dispatch_time(DISPATCH_TIME_NOW,(int64_t)(2*NSEC_PER_SEC)),dispatch_get_main_queue(),^{ self.label.text=@""; }); } } @end
2、识别器检测
// //ViewController.m //Swipes // //CreatedbyJierismon16/8/4. //Copyright©2016年Jierism.Allrightsreserved. // #import"ViewController.h" @interfaceViewController() @property(weak,nonatomic)IBOutletUILabel*label; @property(nonatomic)CGPointgestureStartPoint; @end @implementationViewController -(void)viewDidLoad{ [superviewDidLoad]; //Doanyadditionalsetupafterloadingtheview,typicallyfromanib. //创建两个手势识别器 //1、水平方向识别器 UISwipeGestureRecognizer*horizontal=[[UISwipeGestureRecognizeralloc]initWithTarget:selfaction:@selector(reportHorizontalSwipe:)]; horizontal.direction=UISwipeGestureRecognizerDirectionLeft|UISwipeGestureRecognizerDirectionRight; [self.viewaddGestureRecognizer:horizontal]; //2、垂直方向识别器 UISwipeGestureRecognizer*vertical=[[UISwipeGestureRecognizeralloc]initWithTarget:selfaction:@selector(reportVerticalSwipe:)]; vertical.direction=UISwipeGestureRecognizerDirectionUp|UISwipeGestureRecognizerDirectionDown; [self.viewaddGestureRecognizer:vertical]; } -(void)didReceiveMemoryWarning{ [superdidReceiveMemoryWarning]; //Disposeofanyresourcesthatcanberecreated. } -(void)reportHorizontalSwipe:(UIGestureRecognizer*)recognizer { self.label.text=@"Horizontalswipedetected"; //2s后擦除文本 dispatch_after(dispatch_time(DISPATCH_TIME_NOW,(int64_t)(2*NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ self.label.text=@""; }); } -(void)reportVerticalSwipe:(UIGestureRecognizer*)recognizer { self.label.text=@"Verticalswipedetected"; //2s后擦除文本 dispatch_after(dispatch_time(DISPATCH_TIME_NOW,(int64_t)(2*NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ self.label.text=@""; }); } @end
三、实现多指轻扫
// //ViewController.m //Swipes // //CreatedbyJierismon16/8/4. //Copyright©2016年Jierism.Allrightsreserved. // #import"ViewController.h" @interfaceViewController() @property(weak,nonatomic)IBOutletUILabel*label; @property(nonatomic)CGPointgestureStartPoint; @end @implementationViewController -(void)viewDidLoad{ [superviewDidLoad]; //Doanyadditionalsetupafterloadingtheview,typicallyfromanib. for(NSUIntegertouchCount=1;touchCount<=5;touchCount++){ //创建两个手势识别器 //1、水平方向识别器 UISwipeGestureRecognizer*horizontal=[[UISwipeGestureRecognizeralloc]initWithTarget:selfaction:@selector(reportHorizontalSwipe:)]; horizontal.direction=UISwipeGestureRecognizerDirectionLeft|UISwipeGestureRecognizerDirectionRight; [self.viewaddGestureRecognizer:horizontal]; //2、垂直方向识别器 UISwipeGestureRecognizer*vertical=[[UISwipeGestureRecognizeralloc]initWithTarget:selfaction:@selector(reportVerticalSwipe:)]; vertical.direction=UISwipeGestureRecognizerDirectionUp|UISwipeGestureRecognizerDirectionDown; [self.viewaddGestureRecognizer:vertical]; } } -(void)didReceiveMemoryWarning{ [superdidReceiveMemoryWarning]; //Disposeofanyresourcesthatcanberecreated. } -(NSString*)descriptionForTouchCount:(NSUInteger)touchCount { switch(touchCount){ case1: return@"Single"; case2: return@"Double"; case3: return@"Triple"; case4: return@"Quadruple"; case5: return@"Quintuple"; default: return@""; } } -(void)reportHorizontalSwipe:(UIGestureRecognizer*)recognizer { self.label.text=[NSStringstringWithFormat:@"%@Horizontalswipedetected",[selfdescriptionForTouchCount:[recognizernumberOfTouches]]]; //2s后擦除文本 dispatch_after(dispatch_time(DISPATCH_TIME_NOW,(int64_t)(2*NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ self.label.text=@""; }); } -(void)reportVerticalSwipe:(UIGestureRecognizer*)recognizer { self.label.text=[NSStringstringWithFormat:@"%@Verticalswipedetected",[selfdescriptionForTouchCount:[recognizernumberOfTouches]]]; //2s后擦除文本 dispatch_after(dispatch_time(DISPATCH_TIME_NOW,(int64_t)(2*NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ self.label.text=@""; }); } @end
四、检测多次轻点
// //ViewController.m //TapTaps // //CreatedbyJierismon16/8/4. //Copyright©2016年Jierism.Allrightsreserved. // #import"ViewController.h" @interfaceViewController() @property(weak,nonatomic)IBOutletUILabel*singleLabel; @property(weak,nonatomic)IBOutletUILabel*doubleLabel; @property(weak,nonatomic)IBOutletUILabel*tripleLabel; @property(weak,nonatomic)IBOutletUILabel*quadrupleLabel; @end @implementationViewController -(void)viewDidLoad{ [superviewDidLoad]; //Doanyadditionalsetupafterloadingtheview,typicallyfromanib. //创建4个点击手势识别器 UITapGestureRecognizer*singleTap=[[UITapGestureRecognizeralloc]initWithTarget:selfaction:@selector(singleTap)]; singleTap.numberOfTapsRequired=1; singleTap.numberOfTouchesRequired=1; //附加到视图 [self.viewaddGestureRecognizer:singleTap]; UITapGestureRecognizer*doubleTap=[[UITapGestureRecognizeralloc]initWithTarget:selfaction:@selector(doubleTap)]; doubleTap.numberOfTapsRequired=2; doubleTap.numberOfTouchesRequired=1; [self.viewaddGestureRecognizer:doubleTap]; //当doubleTap响应“失败”才运行singleTap [singleTaprequireGestureRecognizerToFail:doubleTap]; UITapGestureRecognizer*tripleTap=[[UITapGestureRecognizeralloc]initWithTarget:selfaction:@selector(tripleTap)]; tripleTap.numberOfTapsRequired=3; tripleTap.numberOfTouchesRequired=1; [self.viewaddGestureRecognizer:tripleTap]; [doubleTaprequireGestureRecognizerToFail:tripleTap]; UITapGestureRecognizer*quadrupleTap=[[UITapGestureRecognizeralloc]initWithTarget:selfaction:@selector(quadrupleTap)]; quadrupleTap.numberOfTapsRequired=4; quadrupleTap.numberOfTouchesRequired=1; [self.viewaddGestureRecognizer:quadrupleTap]; [tripleTaprequireGestureRecognizerToFail:quadrupleTap]; } -(void)singleTap { self.singleLabel.text=@"SingleTapDetected"; dispatch_after(dispatch_time(DISPATCH_TIME_NOW,(int64_t)(2*NSEC_PER_SEC)),dispatch_get_main_queue(),^{ self.singleLabel.text=@""; }); } -(void)doubleTap { self.doubleLabel.text=@"DoubleTapDetected"; dispatch_after(dispatch_time(DISPATCH_TIME_NOW,(int64_t)(2*NSEC_PER_SEC)),dispatch_get_main_queue(),^{ self.doubleLabel.text=@""; }); } -(void)tripleTap { self.tripleLabel.text=@"TripleTapDetected"; dispatch_after(dispatch_time(DISPATCH_TIME_NOW,(int64_t)(2*NSEC_PER_SEC)),dispatch_get_main_queue(),^{ self.tripleLabel.text=@""; }); } -(void)quadrupleTap { self.quadrupleLabel.text=@"QuadrupleTapDetected"; dispatch_after(dispatch_time(DISPATCH_TIME_NOW,(int64_t)(2*NSEC_PER_SEC)),dispatch_get_main_queue(),^{ self.quadrupleLabel.text=@""; }); } @end
五、检测捏合和旋转
#import<UIKit/UIKit.h> @interfaceViewController:UIViewController<UIGestureRecognizerDelegate> @end
// //ViewController.m //PinchMe // //CreatedbyJierismon16/8/4. //Copyright©2016年Jierism.Allrightsreserved. // #import"ViewController.h" @interfaceViewController() @property(strong,nonatomic)UIImageView*imageView; @end @implementationViewController //当前缩放比例,先前缩放比例 CGFloatscale,previousScale; //当前旋转角度,先前旋转角度 CGFloatrotation,previousRotation; -(void)viewDidLoad{ [superviewDidLoad]; //Doanyadditionalsetupafterloadingtheview,typicallyfromanib. previousScale=1; UIImage*image=[UIImageimageNamed:@"yosemite-meadows"]; self.imageView=[[UIImageViewalloc]initWithImage:image]; //对图像启用交互功能 self.imageView.userInteractionEnabled=YES; self.imageView.center=self.view.center; [self.viewaddSubview:self.imageView]; //建立捏合手势识别器 UIPinchGestureRecognizer*pinchGesture=[[UIPinchGestureRecognizeralloc]initWithTarget:selfaction:@selector(doPinch:)]; pinchGesture.delegate=self; [self.imageViewaddGestureRecognizer:pinchGesture]; //建立旋转手势识别器 UIRotationGestureRecognizer*rotationGesture=[[UIRotationGestureRecognizeralloc]initWithTarget:selfaction:@selector(doRorate:)]; rotationGesture.delegate=self; [self.imageViewaddGestureRecognizer:rotationGesture]; } -(BOOL)gestureRecognizer:(UIGestureRecognizer*)gestureRecognizershouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer*)otherGestureRecognizer { //允许捏合手势和旋转手势同时工作。否则,先开始的手势识别器会屏蔽另一个 returnYES; } //根据手势识别器中获得的缩放比例和旋转角度对图像进行变换 -(void)transformImageView { CGAffineTransformt=CGAffineTransformMakeScale(scale*previousScale,scale*previousScale); t=CGAffineTransformRotate(t,rotation+previousRotation); self.imageView.transform=t; } -(void)doPinch:(UIPinchGestureRecognizer*)gesture { scale=gesture.scale; [selftransformImageView]; if(gesture.state==UIGestureRecognizerStateEnded){ previousScale=scale*previousScale; scale=1; } } -(void)doRorate:(UIRotationGestureRecognizer*)gesture { rotation=gesture.rotation; [selftransformImageView]; if(gesture.state==UIGestureRecognizerStateEnded){ previousRotation=rotation+previousRotation; rotation=0; } } @end
六、自定义手势
// //CheckMarkRecognizer.m //CheckPlease // //CreatedbyJierismon16/8/4. //Copyright©2016年Jierism.Allrightsreserved. // #import"CheckMarkRecognizer.h" #import"CGPointUtils.h" #import<UIKit/UIGestureRecognizerSubclass.h>//一个重要目的是使手势识别器的state属性可写,子类将使用这个机制断言我们所观察的手势已成功完成 //设置检测范围 staticCGFloatconstkMinimunCheckMarkAngle=80; staticCGFloatconstkMaximumCheckMarkAngle=100; staticCGFloatconstkMinimumCheckMarkLength=10; @implementationCheckMarkRecognizer{ //前两个实例变量提供之前的线段 CGPointlastPreviousPoint; CGPointlastCurrentPoint; //画出的线段长度 CGFloatlineLengthSoFar; } //用lastPreviousPoint和lastCurrentPoint组成第一条线段,跟第二条线段形成角度去完成手势 -(void)touchesBegan:(NSSet<UITouch*>*)toucheswithEvent:(UIEvent*)event { [supertouchesBegan:toucheswithEvent:event]; UITouch*touch=[touchesanyObject]; CGPointpoint=[touchlocationInView:self.view]; lastPreviousPoint=point; lastCurrentPoint=point; lineLengthSoFar=0.0; } -(void)touchesMoved:(NSSet<UITouch*>*)toucheswithEvent:(UIEvent*)event { [supertouchesMoved:toucheswithEvent:event]; UITouch*touch=[touchesanyObject]; CGPointpreviousPoint=[touchpreviousLocationInView:self.view]; CGPointcurrentPoint=[touchlocationInView:self.view]; CGFloatangle=angleBetweenLines(lastPreviousPoint,lastCurrentPoint,previousPoint,currentPoint); if(angle>=kMinimunCheckMarkAngle&&angle<=kMaximumCheckMarkAngle&&lineLengthSoFar>kMinimumCheckMarkLength){ self.state=UIGestureRecognizerStateRecognized; } lineLengthSoFar+=distanceBetweenPoints(previousPoint,currentPoint); lastPreviousPoint=previousPoint; lastCurrentPoint=currentPoint; } @end
// //ViewController.m //CheckPlease // //CreatedbyJierismon16/8/4. //Copyright©2016年Jierism.Allrightsreserved. // #import"ViewController.h" #import"CheckMarkRecognizer.h" @interfaceViewController() @property(weak,nonatomic)IBOutletUIImageView*imageView; @end @implementationViewController -(void)viewDidLoad{ [superviewDidLoad]; //Doanyadditionalsetupafterloadingtheview,typicallyfromanib. CheckMarkRecognizer*check=[[CheckMarkRecognizeralloc]initWithTarget:selfaction:@selector(doCheck:)]; [self.viewaddGestureRecognizer:check]; self.imageView.hidden=YES; } -(void)didReceiveMemoryWarning{ [superdidReceiveMemoryWarning]; //Disposeofanyresourcesthatcanberecreated. } -(void)doCheck:(CheckMarkRecognizer*)check { self.imageView.hidden=NO; dispatch_after(dispatch_time(DISPATCH_TIME_NOW,(int64_t)(2*NSEC_PER_SEC)),dispatch_get_main_queue(),^{ self.imageView.hidden=YES; }); } @end
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。