day9---触摸事件与手势

触摸事件与手势
一 触摸事件
1.1 响应者对象
在iOS中不是任何对象都能处理事件的,只有继承了UIResponder的对象才能接受并处理事件,称为“响应者对象”;UIView,UIApplication,AppDelegate,UIViewController,都是继承自UIResponder,因此他们都是响应者对象,都能接受并处理事件;

1.2 UIResponder内部提供以下方法来处理事件
当手指开始触摸屏幕的时候
touchesBegain…..
当手指在屏幕中移动的时候
touchesMoved….
当手指离开屏幕的一瞬间
touchesEnded…..
触摸结束前,某个系统打断触摸过程(比如:电话呼入)
touchesCancled

见【Demo】-【1-UITouch】
  • (void)viewDidLoad {
    [super viewDidLoad];

    NSArray imageNames = @[@"CyanSquare",@"MagentaSquare",@"YellowSquare"];
    for (int i=0; i<3; i++) {
    UIImageView imgView = [[UIImageView alloc] initWithFrame:CGRectMake(i80, 50+i
    80, 80, 80)];
    imgView.image = [UIImage imageNamed:imageNames[i]];
    //开启用户交互事件
    imgView.userInteractionEnabled = YES;
    [self.view addSubview:imgView];
    }

}

//当手指开始触摸屏幕的时候
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{

NSInteger count = event.allTouches.count;

// NSLog(@"%ld",count);

// NSLog(@"开始触摸了");
//拿到当前手指UITouch对象
UITouch *touch = [touches anyObject];

//touch.view获得当前触摸的视图
if ([touch.view isKindOfClass:[UIImageView class]]) {
    if(count == 2 ){
        NSLog(@"现在是两根手指点击图片");
    }
}

}

//当手指在屏幕中移动的时候
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{

// NSLog(@"开始移动了");
//拿到当前手指触摸屏幕对应的UITouch对象
UITouch *touch = [touches anyObject];
//如果当前触摸的视图是UIImageView视图类型
if ([touch.view isKindOfClass:[UIImageView class]]) {
//获得当前触摸的点在self.view上的位置
CGPoint point = [touch locationInView:self.view];
// NSLog(@"x = %lf y= %lf",point.x,point.y);
//实现让图片跟手指移动(把手指的位置赋值给图片的中心点)
touch.view.center = point;
//把当前触摸的这个view放在最上层显示
[self.view bringSubviewToFront:touch.view];
}

}

//当手指离开屏幕的时候
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{

// NSLog(@"离开屏幕");
UITouch *touch = [touches anyObject];
if ([touch.view isKindOfClass:[UIImageView class]]) {

    if (touch.tapCount == 2) {
        //表示双击
        //修改touch.view的宽高
        CGRect frame = touch.view.frame;
        frame.size.width +=10;
        frame.size.height+=10;
        touch.view.frame = frame;
        [self.view bringSubviewToFront:touch.view];
    }
    
    
}

}

1.3UITouch
    当用户用一根手指触摸屏幕的时候,会创建一个与手指相关联的UITouch对象,一根手指对应一个UITouch对象;
    作用:
    1)内部保存着跟手指相关的信息,比如触摸的位置,触摸的时间阶段。。。
    2)当手指移动的时候,系统会更新同一个UITouch对象,使之能够一直保存该手指的位置
    3)当手指离开屏幕的时候,系统会销毁UITouch对象;
    
UITouch的常用方法:
-(CGPoint)LocationInView:(UIView *)view;    
返回值表示触摸在view上的位置
这里的返回值针对的是view的坐标系
参数传nil,返回的触摸位置是在UIWindow的坐标位置;


1.4事件的产生和传递
》发生触摸事件后,系统会将该事件加入到由UIApplication管理的事件队列中
》UIApplication会从事件队列(先进先出)中取出最前面的事件,并将事件分发下去以便处理,通常,先发放事件给程序主窗口;
》主窗口就会在视图的层次结构中找到一个最合适的视图来处理该事件;
》找到之后,就会调用响应的touchesBegan....等相关方法来做具体的事件处理;


1.5如何找到最合适的视图来处理事件?
    1)自己是否能接受触摸事件
    2)触摸点是否在自己身上
    3)从后往前遍历子视图,重复前两个步骤;
    4)如果没有符合条件的子视图,那么就自己最合适处理;

【如果父视图不能接受触摸事件,那么子视图也不能接受触摸事件】;
UIView不能接受触摸事件的三种情况:
    1)userInteractionEnable = NO;
    2)隐藏hidden = YES;
    3)透明alpha = 0~0.01之间;
    UIImageView和UILabel默认不能接受事件;


1.6响应者链的事件传递过程
    找到最合适的视图之后,就会调用touches相关的方法来做具体的处理,这些touches方法的默认做法就是将事件顺着响应者链向上传递,将事件交给上一个响应者来处理。。
1》如果view的控制器存在,view本身如果不处理,那么久传递给控制器处理;
2》如果view的控制器不处理,那么交给它的父视图。。
3》在视图层次结构的最顶级视图,如果也不处理事件,那么交给UIWindow来处理
4》如果UIWindow也不处理,那么就会传递给AppDelegate
5》如果AppDelegate也不处理,就会传递给UIApplication
6》如果UIApplication也不处理,该事件抛弃!!

见【Demo】-【2-UITouchEvent】

二 手势
1.什么是手势?
手势就是用户对视图进行一系列触控的操作。
手势都是UIGestureRecognizer类型的对象

2.手势的种类
》一次性手势
    被视图识别出后值调用一次方法,比如:tap,轻扫(swipe)
》连续性手势
    被视图识别出后手势不停变化是连续调用方法。比如:拖动,缩放,选中,长按。。

3.手势本质
    在程序中手势本质还是对象,当用户在视图上进行触控操作时,视图会识别出相应的手势对象,视图识别出手势的前提是视图已经提前注册了相应的手势对象,当视图识别出手势后,手势对象就会调用对应的方法来处理该动作;

4.如何使用手势
见【Demo】-【3-UIGestureRecognizer】

self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
RootViewController *rvc = [[RootViewController alloc] init];
UINavigationController *nvc = [[UINavigationController alloc] initWithRootViewController:rvc];
self.window.rootViewController = nvc;
  • (void)viewDidLoad {
    [super viewDidLoad];

    NSArray *titles = @[@"Tap",@"Swipe",@"Long",@"Pan",@"Pinch",@"Rotation"];
    CGRect screenBounds = [[UIScreen mainScreen] bounds];
    for (int i=0; i<6; i++) {
    UIButton btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    btn.frame = CGRectMake(80, 100+i
    60, screenBounds.size.width-160, 40);
    [btn setTitle:titles[i] forState:UIControlStateNormal];
    btn.backgroundColor = [UIColor magentaColor];
    [btn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];
    btn.tag = 100+i;
    [self.view addSubview:btn];
    }

}

-(void)btnClick:(UIButton *)btn{

NSArray *vcArray = @[@"TapViewController",@"SwipeViewController",@"LongPressViewController",@"PanViewController",@"PinchViewController",@"RotationViewController"];

//通过字符串反射出对应的类对象
Class class = NSClassFromString(vcArray[btn.tag - 100]);
//通过类对象创建对象
UIViewController *vc = [[class alloc] init];
//设置标题
vc.title = [btn currentTitle];
//导航控制器push
[self.navigationController pushViewController:vc animated:YES];

}

  • (void)viewDidLoad {
    [super viewDidLoad];

    UIImage *image = [UIImage imageNamed:@"CyanSquare"];

    UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
    imageView.frame =CGRectMake(0, 0, image.size.width, image.size.height);//尺寸和图片的尺寸一样大
    imageView.center = self.view.center;//居中显示
    imageView.userInteractionEnabled = YES;
    [self.view addSubview:imageView];

    //1.创建手势对象
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapClick:)];

    //2.手势相关的属性
    //点击的次数(默认1)
    tap.numberOfTapsRequired = 1;
    //手指的个数(默认1)
    tap.numberOfTouchesRequired = 1;
    //3.把手势与视图相关联
    [imageView addGestureRecognizer:tap];

}

-(void)tapClick:(UITapGestureRecognizer *)tap{

NSLog(@"响应了");

}

  • (void)viewDidLoad {
    [super viewDidLoad];

    //轻扫手势
    UISwipeGestureRecognizer *swipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeClick:)];
    //设置轻扫的方向
    swipe.direction = UISwipeGestureRecognizerDirectionLeft;

    [self.view addGestureRecognizer:swipe];

UISwipeGestureRecognizer *rSwipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeClick:)];
//右扫
rSwipe.direction = UISwipeGestureRecognizerDirectionRight;
[self.view addGestureRecognizer:rSwipe];

}

-(void)swipeClick:(UISwipeGestureRecognizer *)swipe{
//如果是左扫
if (swipe.direction == UISwipeGestureRecognizerDirectionLeft) {
self.view.backgroundColor = [UIColor magentaColor];
}else{
self.view.backgroundColor = [UIColor greenColor];
}

}

  • (void)viewDidLoad {
    [super viewDidLoad];

    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(100, 100, 200, 100)];
    label.text = @"长按我吧~~~~~";
    label.textAlignment = NSTextAlignmentCenter;
    label.backgroundColor = [UIColor orangeColor];
    label.userInteractionEnabled = YES;
    [self.view addSubview:label];

    UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressClick:)];
    //用几个手指触屏,默认1
    longPress.numberOfTouchesRequired = 1;
    //设置最短长按时间,单位为妙(默认0.5妙)
    longPress.minimumPressDuration = 2;
    //设置手势识别期间所允许的手势可移动范围
    longPress.allowableMovement = 10;

    [label addGestureRecognizer:longPress];

}

-(void)longPressClick:(UILongPressGestureRecognizer *)longPress{

//state属性是所有手势父类提供的方法,用于记录手势的状态;

if (longPress.state == UIGestureRecognizerStateBegan) {
    NSLog(@"长按手势开始响应");
}else if (longPress.state == UIGestureRecognizerStateChanged){
    NSLog(@"长按手势移动中");
}else{
    NSLog(@"长按手势结束");
}

}

  • (void)viewDidLoad {
    [super viewDidLoad];

    UIImage *image = [UIImage imageNamed:@"CyanSquare"];
    UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
    imageView.frame =CGRectMake(0, 0, image.size.width, image.size.height);//尺寸和图片的尺寸一样大
    imageView.center = self.view.center;//居中显示
    imageView.userInteractionEnabled = YES;
    [self.view addSubview:imageView];

//平移手势
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panClick:)];

[imageView addGestureRecognizer:pan];

}

-(void)panClick:(UIPanGestureRecognizer *)pan{

//通过pan手势,能够获取到pan。view在self。view上的偏移量
CGPoint point = [pan translationInView:self.view];

// NSLog(@"x = %.2lf y= %.2lf",point.x,point.y);

//改变中心点的坐标(原来的中心点+偏移量=当前的中心点)
pan.view.center = CGPointMake(pan.view.center.x+point.x, pan.view.center.y+point.y);
//每次调用之后,需要重置手势的偏移量,否则偏移量会自动累加
//CGPointZero = CGPointZero(0,0);
[pan setTranslation:CGPointZero inView:self.view];

}

  • (void)viewDidLoad {
    [super viewDidLoad];

    UIImage *image = [UIImage imageNamed:@"CyanSquare"];
    UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
    imageView.frame =CGRectMake(0, 0, image.size.width, image.size.height);//尺寸和图片的尺寸一样大
    imageView.center = self.view.center;//居中显示
    imageView.userInteractionEnabled = YES;
    [self.view addSubview:imageView];

UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinchClick:)];

[imageView addGestureRecognizer:pinch];

}

-(void)pinchClick:(UIPinchGestureRecognizer *)pinch{
//缩放的系数
NSLog(@"%.2lf",pinch.scale);

//固定写法
pinch.view.transform = CGAffineTransformScale(pinch.view.transform, pinch.scale, pinch.scale);


//重置缩放系数(否则系数会累加)
pinch.scale = 1.0;

}

  • (void)viewDidLoad {
    [super viewDidLoad];

    UIImage *image = [UIImage imageNamed:@"CyanSquare"];
    UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
    imageView.frame =CGRectMake(0, 0, image.size.width, image.size.height);//尺寸和图片的尺寸一样大
    imageView.center = self.view.center;//居中显示
    imageView.userInteractionEnabled = YES;
    [self.view addSubview:imageView];

UIRotationGestureRecognizer *rotation = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotationClick:)];

[imageView addGestureRecognizer:rotation];

}

-(void)rotationClick:(UIRotationGestureRecognizer *)rotation{

//rotation.rotation   手势旋转的角度
rotation.view.transform = CGAffineTransformRotate(rotation.view.transform, rotation.rotation);

//重复角度

// rotation.rotation = 0;
}

你可能感兴趣的:(day9---触摸事件与手势)