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
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。