1、触摸
触摸就是用户的手指放在屏幕上一直到手指离开,触摸是在UIView上进行的,当用户触摸到屏幕时,触摸事件就会产生。实际上任何UI控件都是直接继承或间接继承自UIView,由此可见,所有的UI控件都可以产生触摸事件。
当用户触摸屏幕时,事件会被封装成一个event实例,包含了触摸事件的相关信息,event实例中包含了若干个UITouch实例,一个touch表示一个手指。
2、UITouch类中常用属性
(1)window : 触摸产生时所处的窗口
(2)view: 触摸产生时所处的视图
(3)tapCount: 表示短时间内轻击屏幕的次数,因此可以根据tapCount判断单击、双击或更多的轻击。
(4)phase: 触摸事件在屏幕上有一个周期,即触摸开始、触摸点移动、触摸结束,还有中途取消。而通过phase可以查看当前触摸事件在一个周期内所处的状态。phase是UITouchPhase类型的。这是一个枚举类型,包含了:UITouchPhaseBegan(触摸开始)、UITouchPhaseMoved(接触点移动)、UITouchPhaseStationary(接触点无移动)、UITouchPhaseEnded(触摸结束)、UITouchPhaseCanceled(触摸取消)
3、响应者链
继承了UIResponder的对象可以作为事件的响应者,当用户与某个控件交互时,该控件将会作为"第一响应者",第一响应者将作为响应者链的开始,该事件首先被发送给第一响应者,若不响应事件,将沿着响应者链一直向下传递,直到被某个响应者处理。
通常来说,第一响应者都是UIView控件或UIView子类控件,当用户触摸该控件后,事件最先由该控件本身处理;如果该控件自身不处理事件,事件就会被传递到它的对应的视图控制器;如果该视图控制器不存在或不处理该事件,事件就会被传递到父View控件对应的视图控制器;如果事件还不被处理,事件就会传递到UIWindow;如果UIWindow对象也不处理,事件则会传递到UIApplication的委托对象;如果UIApplication也不处理该事件,那么该事件就会被丢弃。
4、响应触摸的方法
void)touchesBegan:(NSSet *)touches withEvent:(UIEvent
在该方法中,用event 的allTouches方法获取当前的触摸对象的所有集合
NSSet *allTouches = [event allTouches];
NSLog(@"手指数量:%li",allTouches.count);
//获取任意一个触摸对象
UITouch *touch = [allTouches anyObject];
NSLog(@"段时间内点击的次数:%li",touch.tapCount);
//返回触摸点的坐标
CGPoint point = [touch locationInView:touch.view];
NSLog(@"x is %.2f, y is %.2f",point.x,point.y);
void)touchesMoved:(NSSet *)touches withEvent:(UIEvent
void)touchesEnded:(NSSet *)touches withEvent:(UIEvent
void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent
5、手势
手势处理器(UIGestureRecognizer)使得处理用户触摸事件更加简单,而且无论处理哪种触摸手势,都可面向Gesture Recognizer编程。
UIGestureRecognizer提供了如下子类来处理具体的手势
UITapGestureRecognizer:处理用户点击手势的手势处理器
UIPinchGestureRecognizer:处理用户捏合手势的手势处理器
UIPanGestureRecognizer:处理用户拖拽手势的手势处理器
UISwipeGestureRecognizer:处理用户轻扫的手势处理器
UIRotationGestureRecognizer:处理用户旋转手势的手势处理器
UILongPressGestureRecognizer:处理用户长按手势的手势处理器
(1)使用手势处理器处理用户触摸手势的步骤如下:
根据程序需要处理的手势创建对应的手势处理器对象。创建手势处理器时需要指定target和action参数;
如果该UI控件不允许用户交互,则将该UI控件的userInteractionEnabled属性设置为YES;如果希望该控件可支持多点触摸,还需要将mutipleTouchEnabled设置为YES
调用该UI控件的addGestureRecognizer:方法添加该手势处理器。
(2)UIGestureRecognizer作为所有手势处理器的基类,它提供了如下的常用方法和属性:
-(CGPoint)locationInView:(UIView *)view;返回该手势在view控件中的触摸位置
-(NSUInteger)numberOfTouches;返回该手势包含触摸点的数量;
view:返回激发该手势的UI控件
enabled:用于设置和返回该手势处理器是否可用
state:获取该手势的状态,比如手势开始(UIGestureRecognizerStateBegan),手势改变时(UIGestureRecognizerStateChanged),手势结束时(UIGestureRecognizerStateEnded)
6、点击手势(UITapGestureRecognizer)
该类提供了两个属性:numberOfTapsRequired:指定该手势处理器只处理几次触摸事件
numberOfTouchesRequired:指定该手势处理器只处理几个手指的触摸事件
(nonatomic, weak) IBOutlet UILabel *lbGesture;
//实例化一个手势对象
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapClick:)];
tapGesture.numberOfTapsRequired = 1;//点击的次数
//设置手指的数量
tapGesture.numberOfTouchesRequired =1;
[_lbGesture addGestureRecognizer:tapGesture];
void)tapClick:(UITapGestureRecognizer
NSLog(@"轻拍");
//CGPoint point = [tapGesture locationInView:tapGesture.view];//相对于label的坐标
CGPoint point = [tapGesture locationInView:self.view];//相对于self.view的坐标
NSLog(@"x is %.2f,y is %.2f",point.x,point.y);
switch (tapGesture.state) {
case UIGestureRecognizerStateBegan:
NSLog(@"触摸开始");
break;
case UIGestureRecognizerStateChanged:
NSLog(@"改变");
break;
case UIGestureRecognizerStateEnded:
NSLog(@"结束");
break;
default:
break;
}
}
7、捏合手势(UIPinchGestureRecognizer)
它有两个属性获取捏合的相关信息:scale:获取捏合的比例
velocity:获取捏合的速度
*pinchGesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinchGesture:)];
[_imageView addGestureRecognizer:pinchGesture];
void)pinchGesture:(UIPinchGestureRecognizer
CGFloat scale = gesture.scale;//捏合比例
//NSLog(@"%.2f",scale);
//捏合速度
//CGFloat velocity = gesture.velocity;
//_imageView.transform = CGAffineTransformMakeScale(scale, scale);
//在原有的基础上进行缩放
_imageView.transform = CGAffineTransformScale(_imageView.transform, scale, scale);
scale = 1.0;
}
8、旋转手势(UIRotationGestureRecognizer)
它有两个属性来获取旋转的相关信息:rotation:获取旋转的角度
velocity:获取旋转的速度
UIRotationGestureRecognizer *rotationGesture = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotationGesture:)];
[_imgView addGestureRecognizer:rotationGesture];
void)rotationGesture:(UIRotationGestureRecognizer
CGFloat rotation = gesture.rotation;
_imgView.transform = CGAffineTransformRotate(_imgView.transform, rotation);
rotation = 0.0f;
}
9、轻扫手势(UISwipeGestureRecognizer)
它设置了两个属性来获取轻扫的相关信息:numberOfTouchesRequired:设置该手势处理器只处理几个手指的触摸事件;direction:设置该手势处理器只处理某个方向的轻扫
在应用中可以只创建某个方向的手势,也可以同时将四个方向的手势加到同一控件中。
(1)为控件添加一个方向的轻扫手势处理器
// 创建手势处理器,指定使用该控制器的handleSwipe方法处理手势
UISwipeGestureRecognizer *swipeGestureLeft=[[UISwipeGestureRecognizer alloc] initWithTarget:selfaction:@selector(handleSwipe:)];
// 设置该手势处理器只处理1个手指的轻扫手势
swipeGestureLeft.numberOfTouchesRequired=1;
// 设置该手势处理器的轻扫方向
swipeGestureLeft.direction=UISwipeGestureRecognizerDirectionLeft;
// 为self.view添加手势处理器
[self.view addGestureRecognizer:swipeGestureLeft];
(2)为控件添加4个方向的轻扫手势处理器
for (int i = 0; i < 4; i++) {
UISwipeGestureRecognizer *swipeGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipe:)];
setDirection:1 << i];//设置滑动手势为左滑动
self.view addGestureRecognizer:swipeGesture];
}
void)swipe:(UISwipeGestureRecognizer
//NSLog(@"滑动");
switch (swipeRecognizer.direction) {
case UISwipeGestureRecognizerDirectionLeft:
NSLog(@"向左");
break;
case UISwipeGestureRecognizerDirectionRight:
NSLog(@"向右");
break;
case UISwipeGestureRecognizerDirectionUp:
NSLog(@"向上");
break;
case UISwipeGestureRecognizerDirectionDown:
NSLog(@"向下");
break;
default:
break;
}
}
10、拖动手势(UIPanGestureRecognizer)
maximumNumaberOfTouches:设置该手势处理器最多支持几个手指的拖动
minimumNumberOfTouches:设置该手势处理器最少需要几个手指拖动
tranlationInView:获取该拖动手势在指定控件上的位移。该方法返回一个CGPoint类型,该结构体中的x的值代表水平方向的位移,y代表垂直方向的位移
velocityInView:获取该拖动手势在指定控件上的拖动速度。该方法返回一个CGPoint类型,该结构体中的x的值代表水平方向的移动速度,y的值代表垂直方向的移动速度
*panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panHandler:)];
panGesture.minimumNumaberOfTouches = 1;
maximumNumaberOfTouches = 2;
[_imageView addGestureRecognizer:panGesture];
void)panHandler:(UIPanGestureRecognizer
CGPoint point = [panGesture translationInView:panGesture.view];
_imageView.transform = CGAffineTransformTranslate(_imageView.transform, point.x, point.y);
[panGesture setTranslation:CGPointMake(0, 0) inView:_imageView];
}
11、长按手势(UILongPressGestureRecognizer)
minimumPressDuration:指定用户至少在屏幕上按下多少秒才会触发该长按手势,默认值是0.5
allowableMovement指定用户移动手指的最大距离
numberOfTouchesRequired:指定必须使用几个手指在屏幕上长按才会发出该手势
*pressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(pressGesture:)];
minimumPressDuration = 1; //设置至少在屏幕上按下多少秒才能长按手势
allowableMovement = 1; //设置长按手势允许用户移动手指的最大距离
pressGesture.numberOfTouchesRequired = 1; //设置必须使用几个手指长按才会发出该手势
[_lbTitle addGestureRecognizer:pressGesture];
void)pressGesture:(UILongPressGestureRecognizer
if (gesture.state == UIGestureRecognizerStateBegan) {
[self becomeFirstResponder];
UIMenuController *menuController = [UIMenuController sharedMenuController];
UIMenuItem *_shareItem= [[UIMenuItem alloc] initWithTitle:@"分享" action:@selector(shareClick)];
UIMenuItem *_copyItem = [[UIMenuItem alloc] initWithTitle:@"复制" action:@selector(copyClick)];
UIMenuItem *_translaterItem = [[UIMenuItem alloc] initWithTitle:@"转发" action:@selector(translaterClick)];
menuItems = @[_shareItem,_copyItem,_translaterItem];
[menuController setTargetRect:_lbTitle.bounds inView:_lbTitle];
update];
setMenuVisible:YES animated:YES];
}
}
void)shareClick{
NSLog(@"分享");
}
void)copyClick{
NSLog(@"复制");
}
void)translaterClick{
NSLog(@"转发");
}
#pragma mark UIMenuController
//使menu所处的View成为第一响应者
BOOL)canBecomeFirstResponder{
return YES;
}
BOOL)canPerformAction:(SEL)action withSender:(id)sender{
if (action == @selector(shareClick)) {
return YES;
else if (action == @selector(copyClick)){
return YES;
else if (action == @selector(translaterClick)){
return YES;
}
return [super canPerformAction:action withSender:sender];
}
12、若想要两个不同的手势加在同一个控件上,则可以用以下方法来执行
//继承一个手势控件
@interface MyRotation : UIRotationGestureRecognizer
@end
MyRotation
/*
是否阻止另一个手势
*/
BOOL)canPreventGestureRecognizer:(UIGestureRecognizer
return NO;
}
BOOL)canBePreventedGestureRecognizer:(UIGestureRecognizer
return NO;
}
*pinchGesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinchGesture:)];
[_imgView addGestureRecognizer:pinchGesture];
MyRotation *rotationGesture = [[MyRotation alloc] initWithTarget:self action:@selector(rotationGesture:)];
[_imgView addGestureRecognizer:rotationGesture];
void)rotationGesture:(UIRotationGestureRecognizer
CGFloat rotation = gesture.rotation;
_imgView.transform = CGAffineTransformRotate(_imgView.transform, rotation);
rotation = 0.0f;
}
void)pinchGesture:(UIPinchGestureRecognizer
CGFloat scale = gesture.scale;
_imgView.transform = CGAffineTransformScale(_imgView.transform, scale, scale);
scale = 1.0f;
}
这样图片就可以一边旋转一边移动了。