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;
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,519评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,842评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,544评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,742评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,646评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,027评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,513评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,169评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,324评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,268评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,299评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,996评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,591评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,667评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,911评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,288评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,871评论 2 341

推荐阅读更多精彩内容