iOS触摸事件(基础)

对触摸事件进行一个基本整理吧,最基础的滑动事件

我们一般写demo最简单的方法就是写一个touchBegin方法,将事件写在里面,敲击屏幕做出对应事件就好了,但是具体有些什么东西,我们来探讨一下。

  • 基本点击事件,按照iOS的尿性,有点击,肯定有移动,有点击结束等一系列方法
    如下:可以多指,但是不建议
// 点击的时候调用
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
// 点击之后不松手,移动的时候调用
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
// 点击点离开屏幕的时候点用,点击结束
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
// 点击取消的时候调用:比如电话打入
- (void)touchesCancelled:(nullable NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
  • iOS9以后又新出了一系列的关于3Dtouch的点击事件
- (void)pressesBegan:(NSSet<UIPress *> *)presses withEvent:(nullable UIPressesEvent *)event NS_AVAILABLE_IOS(9_0);
- (void)pressesChanged:(NSSet<UIPress *> *)presses withEvent:(nullable UIPressesEvent *)event NS_AVAILABLE_IOS(9_0);
- (void)pressesEnded:(NSSet<UIPress *> *)presses withEvent:(nullable UIPressesEvent *)event NS_AVAILABLE_IOS(9_0);
- (void)pressesCancelled:(NSSet<UIPress *> *)presses withEvent:(nullable UIPressesEvent *)event NS_AVAILABLE_IOS(9_0);
  • iOS3增加的摇一摇方法,加速计事件
- (void)motionBegan:(UIEventSubtype)motion withEvent:(nullable UIEvent *)event NS_AVAILABLE_IOS(3_0);
- (void)motionEnded:(UIEventSubtype)motion withEvent:(nullable UIEvent *)event NS_AVAILABLE_IOS(3_0);
- (void)motionCancelled:(UIEventSubtype)motion withEvent:(nullable UIEvent *)event NS_AVAILABLE_IOS(3_0);
  • 最后这两个方法是用来接收远程事件的,比如播放器进入后台,点击外部组件,调用APP的事件方法
// 返回是否接收外部远程事件
- (BOOL)canPerformAction:(SEL)action withSender:(nullable id)sender NS_AVAILABLE_IOS(3_0);
// 这个就是接收事件处理方法
- (void)remoteControlReceivedWithEvent:(nullable UIEvent *)event NS_AVAILABLE_IOS(4_0);

简单的点击事件

我们今天仅仅对点击事件来进行个整理

  • iOS中不是任何对象都能处理事件,只有继承了UIResponder的对象才能接收并处理事件,我们称之为“响应者对象”
  • UIApplication、UIViewController、UIView都继承自UIResponder,因此它们都是响应者对象,都能够接收并处理事件
  1. 四个触摸事件处理方法中,都有NSSet *touches和UIEvent *event两个参数。
  2. 如果两根手指同时触摸一个view,那么view只会调用touchesBegan:withEvent:方法一次,touches参数里有两个UITouch对象
  3. 如果两根手指一前一后分开触摸同一个view,那么view分别调用两次
    touchesBegan:withEvent:方法,并且每次调用时的touches参数只包含一个UITouch对象
  4. 根据touches的UITouch的个数可以判断是单点触摸还是多点触摸
UITouch
  • 当用户用一根手指触摸屏幕,会创建一个与手指相关联的UITouch对象
  • 一根手指对应一个UITouch对象
& UITouch的作用
  • 保存着跟手指相关的信息,比如触摸的对象,时间,阶段
  • 当手指移动时,系统会更新同一个UITouch对象,使之能够一直保持该手指在的触摸位置
  • 当手指离开屏幕的时候,系统会销毁这个UITouch对象

*** 提示:在iPhone开发中,要避免使用双击时间!***

& UITouch的属性

触摸产生时所处的窗口

@property(nonatomic,readonly,retain) UIWindow *window;

触摸产生时所处的视图

@property(nonatomic,readonly,retain) UIView *view;

短时间内点按屏幕的次数,可以根据tapCount判断单击、双击或更多的点击

@property(nonatomic,readonly) NSUInteger tapCount;```

记录了触摸事件产生或变化时的时间,单位是s
```objc 
@property(nonatomic,readonly) NSTimeInterval timestamp;```

当前触摸事件所处的状态
```objc
@property(nonatomic,readonly) UITouchPhase phase;
& UITouch的方法
/**
* 返回值表示触摸在view上的位置
* 这里返回的位置是针对view的坐标系的(以view的左上角为原点(0, 0))
* 调用时传入的view参数为nil的话,返回的是触摸点在UIWindow的位置
*/
- (CGPoint)locationInView:(UIView *)view;

// 该方法记录了前一个触摸点的位置
- (CGPoint)previousLocationInView:(UIView *)view;

UIEvent

  • 每产生一个事件,就会产生一个UIEvent对象
  • UIEvent:称为事件对象,记录产生的时刻类型

#######& 常见属性

  • 事件类型
@property(nonatomic,readonly) UIEventType type;
@property(nonatomic,readonly) UIEventSubtype  subtype;
  • 事件产生的时间
@property (nonatomic, readonly) NSTimeInterval timestamp;

Example:

我们做两个Demo测试一下

第一个Demo

要求:在控制器的View上有一个小的view,这个view随着我们的拖动而移动

// 这个要求实现起来很简单,只需要在touchesMoved:方法里进行操作即可
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    // 因为是NSSet对象,所以我们没办法根据下标取出来内部组件
    // 打印一下看看内部
//    NSLog(@"%zd",touches.count);
    UITouch *touch = [touches anyObject];
    // locationInView:方法取出当前点坐标
    CGPoint curP = [touch locationInView:self];
    // previousLocationInView当前点的前一个点
    CGPoint preP = [touch previousLocationInView:self];
    // precise前缀用于更精确的描点
//    NSLog(@"preciseLocationInView%@",NSStringFromCGPoint([touch preciseLocationInView:self]));
    
    // 获取x轴偏移量
    CGFloat offsetX = curP.x - preP.x;
    // 获取y轴偏移量
    CGFloat offsetY = curP.y - preP.y;
    
    // 改变view的位置 (frame,center,transform)
    self.transform = CGAffineTransformTranslate(self.transform, offsetX, offsetY);
    NSLog(@"%s",__func__);    
}

上面这段代码只要想说明的就是如何拿到这些点击的点,如果去做一些效果的事件

我们来做一个小玩意儿来玩一下

第二个Demo

要求:画板,点击顶部颜色,可以在view上画线,点击撤销,取消最近一次画的线,如下图所示:

Snip20160311_1.png
Snip20160311_3.png

思路:把所以的触发点放到数组里,然后描绘出来
直接上代码了
.h文件里提供外界方法名

-(id)initWithFrame:(CGRect)frame
      button1Color:(UIColor *)button1Color
      button2Color:(UIColor *)button2Color
      button3Color:(UIColor *)button3Color
      button4Color:(UIColor *)button4Color
    drawPaperColor:(UIColor *)paperColor;

.m文件内部实现

#import "DrawBoard.h"

@interface DrawBoard ()
{
    // 四个颜色按钮
    UIButton *_button1;
    UIButton *_button2;
    UIButton *_button3;
    UIButton *_button4;
    UIButton *_repealButton;
    // 颜色
    UIColor *_color;
    // 存放所有东西的总数组
    NSMutableArray *_ziArray;
}


@end


@implementation DrawBoard

- (id)initWithFrame:(CGRect)frame button1Color:(UIColor *)button1Color button2Color:(UIColor *)button2Color button3Color:(UIColor *)button3Color button4Color:(UIColor *)button4Color drawPaperColor:(UIColor *)paperColor
{
    if ([super initWithFrame:frame]) {
        self.backgroundColor = paperColor;
        
        float width = [UIScreen mainScreen].bounds.size.width;
        
        _button1 = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, width*0.25, 50)];
        _button1.backgroundColor=button1Color;
        [self addSubview:_button1];
        //设置点击事件
        [_button1 addTarget:self action:@selector(changeColor:) forControlEvents:UIControlEventTouchDown];
        
        
        
        _button2 = [[UIButton alloc] initWithFrame:CGRectMake(width*0.25, 0, width*0.25, 50)];
        _button2.backgroundColor=button2Color;
        [self addSubview:_button2];
        [_button2 addTarget:self action:@selector(changeColor:) forControlEvents:UIControlEventTouchDown];
        
        
        _button3 = [[UIButton alloc]initWithFrame:CGRectMake(width*0.5, 0, width*0.25, 50)];
        _button3.backgroundColor=button3Color;
        [self addSubview:_button3];
        [_button3 addTarget:self action:@selector(changeColor:) forControlEvents:UIControlEventTouchDown];
        
        
        _button4 = [[UIButton alloc]initWithFrame:CGRectMake(width*0.75, 0, width*0.25, 50)];
        _button4.backgroundColor=button4Color;
        [self addSubview:_button4];
        [_button4 addTarget:self action:@selector(changeColor:) forControlEvents:UIControlEventTouchDown];
        
        _repealButton = [[UIButton alloc]initWithFrame:CGRectMake(100, [UIScreen mainScreen].bounds.size.height -100, width-200, 50)];
        _repealButton.backgroundColor=[UIColor grayColor];
        [_repealButton setTitle:@"撤销" forState:UIControlStateNormal];
        [self addSubview:_repealButton];
        [_repealButton addTarget:self action:@selector(repeal:) forControlEvents:UIControlEventTouchDown];
        
        
        _ziArray = [[NSMutableArray alloc]init];
        
        _color = [UIColor blackColor];
    }
    return self;
}

- (void)changeColor:(UIButton *)btn
{
    _color = btn.backgroundColor;
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    // 创建数组,每个数组放每一笔的所有点
    NSMutableArray *array = [[NSMutableArray alloc] init];
    
    UITouch *touch = [touches anyObject];
    CGPoint point = [touch locationInView:self];
    NSValue *pointValue = [NSValue valueWithCGPoint:point];
    
    [array addObject:pointValue];
    // 这一个数组放一个笔画,然后每个笔画放到一个总数组里
    [_ziArray addObject:array];
}

- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    CGPoint point = [touch locationInView:self];
    NSValue *pointValue = [NSValue valueWithCGPoint:point];
    // 取出放点的这个数组
    NSMutableArray *traitArray = [_ziArray lastObject];
    [traitArray addObject:pointValue];
    // 画图
    [self setNeedsDisplay];
}

// 开始画图
- (void)drawRect:(CGRect)rect
{
    for (int i = 0; i < [_ziArray count]; i++) {
        
        // NSMutableArray *traitArray=[[NSMutableArray alloc] init];错误
        
        NSMutableArray *traitArray = [_ziArray objectAtIndex:i];
        // 拿起画笔的方法
        // 这个方法只有在drawRect:方法里才能调用
        CGContextRef context = UIGraphicsGetCurrentContext();
        // 设置画笔的粗细。。
        CGContextSetLineWidth(context,5.0f );
        // 设置画笔的颜色
        CGContextSetStrokeColorWithColor(context, [[traitArray objectAtIndex:0] CGColor]);
        for (int j = 1; j < [traitArray count]-1; j++) {
            NSValue *pointValue = [traitArray objectAtIndex:j];
            
            CGPoint firstPoint = [pointValue CGPointValue ];
            
            NSValue *secondValue = [traitArray objectAtIndex:j+1];
            
            CGPoint secondPoint = [secondValue CGPointValue];
            
            // 设置两点的连线起点,
            CGContextMoveToPoint(context, firstPoint.x, firstPoint.y);
            // 用点连成线,
            CGContextAddLineToPoint(context, secondPoint.x, secondPoint.y);
            
            // 提交画笔
            CGContextStrokePath(context);
        }
    }
}


- (void)repeal:(UIButton *)btn
{
    // 移除最后面的数组
    [_ziArray removeLastObject];
    // 重画
    [self setNeedsDisplay];
}

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

推荐阅读更多精彩内容

  • 本文来自:http://ios.jobbole.com/84081/ 前言: 按照时间顺序,事件的生命周期是这样的...
    HackerOnce阅读 2,830评论 1 10
  • 响应者对象 在iOS中不是任何对象都能处理事件,只有继承了UIResponder的对象才能接收并处理事件。我们称之...
    JonesCxy阅读 689评论 0 0
  • 在iOS开发中经常会涉及到触摸事件。本想自己总结一下,但是遇到了这篇文章,感觉总结的已经很到位,特此转载。作者:L...
    WQ_UESTC阅读 5,987评论 4 26
  • iOS中的事件 响应者对象 - 在iOS中不是任何对象都能处理事件,只有继承了UIResponder的对象才能接收...
    Hevin_Chen阅读 627评论 0 0
  • 本文介绍了iOS中使用频率较高的触摸事件,并阐述了事件产生和传递的过程,以及响应者链的事件传递过程 触摸事件 简介...
    搁浅的青蛙阅读 644评论 0 1