在iOS中,不是任何对象都能处理事件,只有继承了UIResponder
的对象才能接收并处理事件,我们称之为”响应者对象”.(比如UIApplication,UIViewController,UIView
)
UIView
不接收触摸事件的三种情况:
1> 不接受用户交互 :userInteractionEnable = NO;
2> 隐藏 :hidden = YES;
3> 透明:alpha = 0.0 ~ 0.01
触摸事件的4种状态:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
NSLog(@"手指开始接触View表示触摸开始");
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
NSLog(@"随着手指在View上的移动,持续调用touchesMoved");
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
NSLog(@"手指离开View触摸结束");
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event{
NSLog(@"在touchesEnded之前,某个系统事件(如打电话)会打断触摸过程,系统会自动调用touchesCancelled(触摸取消)");
}
四个触摸事件的处理方法中,都有 NSSet *touches
和 UIEvent *event
两个参数;
1、一次完整的触摸过程,只会产生一个事件对象,4个触摸方法都是同一个event
参数;
2、当用户用一根手指触摸屏幕时,会创建一个与手指相关联的UITouch
对象;一根手指对应一个UITouch
对象;多个手指同时触摸会产生多个UITouch
对象,存放在touches
集合中
3、当手指移动时,系统会更新同一个UITouch
对象,使之能够一直保存该手指的触摸位置;当手指离开屏幕时,系统会销毁相应的UITouch
对象。
4、根据touches
中UITouch
个数可以判断出使单点触摸还是多点触摸。
通过下面的代码获取当前触摸的点
UITouch * touch = [touches anyObject];
CGPoint point = [touch locationInView:self.view];
// NSLog(@"%@",NSStringFromCGPoint(point)); // 输出point
在touchesBegan
中 通过判断[[touches anyObject] tapCount]
的值来判断是否单击(为1),双击(为2),或更多的点击.
NSTimeInterval time = [[touches anyObject] timestamp];//记录触摸事件产生或变化时的时间,单位为秒
触摸事件的产生:
1> 发生触摸事件后,系统会将该事件加入到一个由UIApplication
管理的事件队列中;
2> UIApplication
会从事件队列中取出最前面的事件,并将事件分发下去以便处理,通常,先发送事件给应用程序的主窗口(keyWindow
);
3> 主窗口会在视图层次结构中找到一个最合适的视图控件来处理触摸事件,这也是整个事件处理过程的第一步;
4> 找到合适的视图控件后,就会调用视图控件的touches
方法来做具体的事件处理。
寻找响应消息视图的过程
触摸事件的传递:
触摸事件的传递是从父控件传递到子控件;如果父控件不能接收触摸事件,那么子控件就不可能接收到触摸事件。
手势识别功能(Gesture Recognizer)
为了完成手势识别,必须借助于手势识别器:UIGestureRecognizer
。
利用UIGestureRecognizer
,能轻松识别用户在某个view上面做的一些常见手势。
UIGestureRecognizer
是一个抽象类,定义了所有的手势基本行为,使用它的子类才能处理具体的手势
UITapGestureRecognizer(敲击)
UIPinchGestureRecognizer(捏合,用于缩放)
UIPanGestureRecognizer(拖拽)
UISwipeGestureRecognizer(轻扫)
UIRotationGestureRecognizer(旋转)
UILongPressGestureRecognizer(长按)
每一个手势识别器的用法都差不多,比如UITapGestureRecognizer的使用步骤如下:
1> 创建手势识别器对象:
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] init];
2> 设置手势识别器对象的具体属性;
// 连续敲击2次
tap.numberOfTapsRequired = 2;
// 需要2根手指一起敲击
tap.numberOfTouchesRequired = 2;
3> 添加手势识别器到对应的view上;
[self.iconView addGestureRecognizer:tap];
4> 监听手势的触发
[tap addTarget:self action:@selector(tapIconView:)];
手势识别的状态
typedef NS_ENUM(NSInteger, UIGestureRecognizerState) {
// 没有触摸事件发生,所有手势识别的默认状态
UIGestureRecognizerStatePossible,
// 一个手势已经开始但尚未改变或者完成时
UIGestureRecognizerStateBegan,
// 手势状态改变
UIGestureRecognizerStateChanged,
// 手势完成
UIGestureRecognizerStateEnded,
// 手势取消,恢复至Possible状态
UIGestureRecognizerStateCancelled,
// 手势失败,恢复至Possible状态
UIGestureRecognizerStateFailed,
// 识别到手势识别
UIGestureRecognizerStateRecognized = UIGestureRecognizerStateEnded
};
根据捏合手势实现图片缩放
提示:这里以图片中心进行缩放,可以使用另外两个手势Pan和Rotation进行移动(CGAffineTransformTranslate
)和旋转(CGAffineTransformRotate
)
#import "MainViewController.h"
@interface MainViewController ()<UIGestureRecognizerDelegate>
{
CGFloat lastScale;
}
@end
@implementation MainViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(10,90,300,300)];
imageView.image = [UIImage imageNamed:@"黑暗之女"];
imageView.userInteractionEnabled = YES;
[self.view addSubview:imageView];
UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc]initWithTarget:self action:@selector(pinchGesture:)];
pinch.delegate = self;
[imageView addGestureRecognizer:pinch];
lastScale = 1.0; //初始化lastScale为1.0
}
-(void)pinchGesture:(id)sender {
UIPinchGestureRecognizer *pinch = (UIPinchGestureRecognizer*)sender;
[self.view bringSubviewToFront:pinch.view];
//当手指离开屏幕时,将lastScale设置为1.0
if(pinch.state == UIGestureRecognizerStateEnded) {
lastScale = 1.0;
return;
}
CGFloat scale = 1.0 - (lastScale - pinch.scale);
pinch.view.transform = CGAffineTransformScale(pinch.view.transform, scale, scale);
lastScale = pinch.scale;
}
#pragma mark - UIGestureRecognizerDelegate
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return ![gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]];
}
“