iOS学习笔记——触控与手势

触控

  此部分内容已学良久,恨记之甚晚,忙矣,懒矣!本文简而记焉,恐日后忘也。

  在iOS的触控事件中,有触控、事件以及响应者这三个角色,一个触摸则代表了一只手指和屏幕接触这个动作所包含的信息;而事件则包含了若干只手指在整个屏幕触控中整个过程的所有触摸信息,在C#的角度来说很容易会让人误以为是一种方法(或者叫函数)的指针;实际却不然,在这里无论触控和事件都是用于一些存储信息。而响应者则是确确实实的可以对真正的触控事件作相应处理;这三个角色在OC中分别对应着UITouch,UIEvent和UIResponder这三个类。而UIResponder实际上是所有响应者的基类,它定义了常见的响应者的一些编程接口。UIApplication、UIView都继承了UIResponder类,那么凡是继承UIView的类都继承了UIResponder,换句话说说有UIKit里面的控件都能响应手指对屏幕的触控事件。

  在iOS的事件冒泡和在Android中的原理大致一样,但顺序则相反,每当手指接触到屏幕,最先对时间作出相应的是最顶层的视图控件,也就是整棵可视化树里面的叶子节点,然后按着可视化树的一直上溯,,一路上寻找是否有对象处理了这个事件,处理完毕了就停止往上溯,最后到达UIWindow和UIApplication,假如到了UIApplication还是没办法处理这个事件的话app就会认为它不具备处理这个事件的能力,然后把这个事件抛弃。

下面实际说一下实际的事件,按照触控的不同阶段,iOS分了三个事件来处理三种不同的触控阶段

touchesBegan:withEvent:当一只或多只手指触碰屏幕时触发

touchesMoved:withEvent:一只或多只手指在屏幕上移动时

touchesEnded:withEvent:一只活多只手指离开屏幕时

另外还有一个比较特殊的触控事件是手指触控的任一阶段在被系统事件取消时触发 touchesCancelled:withEvent:

下面这个例子则是通过手指在屏幕上的位置显示在左上角的Label中

把storyboard中的控件在ViewController里面建立关联属性

@interface HGNaviView1Controller ()

@property (weak, nonatomic) IBOutlet UILabel *lbStart;

@property (weak, nonatomic) IBOutlet UILabel *lbMove;

@property (weak, nonatomic) IBOutlet UILabel *lbUp;

@end

然后加上下面四个方法,第一个方法TouchLog是用于输出日志信息,日志的内容是当前这个触控是有多少个触控点,和当前触控的阶段,UITouch的属性phase表示的是阶段,它是一个枚举UITouchPhase,枚举值如下

  • UITouchPhaseBegan, 手指触摸屏幕
  • UITouchPhaseMoved, 手指在屏幕上移动。
  • UITouchPhaseStationary, 手指正在触摸的表面,但由于以前的事件没有发生移动。
  • UITouchPhaseEnded, 手指从屏幕上离开。
  • UITouchPhaseCancelled, 取消跟踪触摸,因为当(例如)用户将设备到他或她的脸
-(void)TouchLog:(UITouch *)touch

{

NSLog(@"Touch tapCount %d",touch.tapCount);

NSLog(@"Touch phase %d",touch.phase);

}

接下来的几个方法就是上面介绍到的触控事件的方法,三个方法的内容大致一样,都是从UIEvent里面获取到当前这个事件中所有触控点UITouch,通过遍历的形式调用上面定义的输出触控点信息的方法TouchLog,然后分别把手指最初接触屏幕时的坐标,移动过程中当前的坐标,还有提起手指时的坐标分别输出到视图界面的三个Label中

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

{

for(UITouch *t in event.allTouches)

{

[self TouchLog:t];

}

if(touches.count>1)return;

UITouch *touch=[[event.allTouches allObjects]objectAtIndex:0];

CGPoint locInsSelf=[touch locationInView:self.view];

self.lbStart.text=[[NSString alloc]initWithFormat:@"开始点击的位置是:(%2.3f,%2.3f)",locInsSelf.x, locInsSelf.y ] ;

}

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event

{

for (UITouch *t in event.allTouches)

{

[self TouchLog:t];

}

if(touches.count>1)return;

CGPoint locInsSelf=[[[event.allTouches allObjects]objectAtIndex:0] locationInView:self.view];

self.lbMove.text=[[NSString alloc]initWithFormat:@"移动的位置是:(%2.3f,%2.3f)",locInsSelf.x, locInsSelf.y ] ;

}

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event

{

for (UITouch *t in event.allTouches) {

[self TouchLog:t];

}

if(touches.count>1)return;

CGPoint locInsSelf=[[[event.allTouches allObjects]objectAtIndex:0] locationInView:self.view];

self.lbUp.text=[[NSString alloc]initWithFormat:@"抬起手指的位置是:(%2.3f,%2.3f)",locInsSelf.x, locInsSelf.y ] ;

}

输出的日志和界面如下面两幅图所示

手势

  上面说的触控对于手指接触屏幕触发事件是最基本的,对于触屏手机而言一些固定的手势动作已经赋予了一定的含义,而这些手势是可以用过触控事件来实现,但是iOS也给出了比较简便的实现方式,其实就是手势UIGestureRecognizer,不过它只是一个抽象类,要实现某个具体的手势操作,还得用上它的子类才行,那下面先来介绍一下对于iOS而言有哪些手势

1.点击(Tap)

用于按下或选择一个控件或条目(类似于鼠标的Click动作)、

2.拖动(Drag)

拖动用于实现一些页面的滚动,以及对控件的移动功能。

3.滑动(Flick)

滑动用于实现页面的快速滚动和翻页的功能。

4.横扫(Swipe)

横扫手势用于激活列表项的快捷操作菜单

5.双击(Double Tap)

类似于鼠标的双击动作,通常用于放大并居中显示图片,或恢复原大小(如果当前已经放大)。同时,双击能够激活针对文字编辑菜单。

6.放大(Pinch open)

放大手势可以实现以下功能:打开订阅源,打开文章的详情。放大当前查看的图片或者文字内容。

7.缩小(Pinch close)

缩小手势,可以实现与放大手势相反且对应的功能的功能:关闭订阅源退出到首页,关闭文章退出至索引页。缩小当前查看的图片或者文字内容。

8.长按(Touch &Hold)

在我的订阅页,长按订阅源将自动进入编辑模式,同时选中手指当前按下的订阅源。这时可直接拖动订阅源移动位置。

针对文字长按,将出现放大镜辅助功能。松开后,则出现编辑菜单。

针对图片长按,将出现编辑菜单。

9.摇晃(Shake)

摇晃手势,将出现撤销与重做菜单。主要是针对用户文本输入的。

对于以上9种手势,iOS经过整合通过一下六个类来实现

  • UITapGestureRecognizer
  • UIPinchGestureRecognizer
  • UIRotationGestureRecognizer
  • UISwipeGestureRecognizer
  • UIPanGestureRecognizer
  • UILongPressGestureRecognizer

他们就分别代表了Tap(点击,有单击双击)、Pinch(捏合,有缩小有放大)、Rotation(旋转)、Swipe(滑动,快速移动,是用于监测滑动的方向的)、Pan (拖移,慢速移动,是用于监测偏移的量的)以及 LongPress(长按)

在使用这些手势的时候,需要在ViewController实现他们对应的delegate

@interface HGNaviView2Controller : UIViewController<UIGestureRecognizerDelegate>

{
}

@end

在viewDidLoad中添加以下代码

UITapGestureRecognizer *tap=[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(SimpleTab:)];

tap.numberOfTouchesRequired=2;

[self.view addGestureRecognizer:tap];

UIPinchGestureRecognizer *pin=[[UIPinchGestureRecognizer alloc]initWithTarget:self action:@selector(SimplePinch:)];

[self.view addGestureRecognizer:pin];

对应地要定义相应是方法,分别都是在手势触发的时候输出Log

-(void)SimpleTab:(UITapGestureRecognizer *)recognizer

{

NSLog(@"NumberOfTouches %d", recognizer.numberOfTouches);

}

-(void)SimplePinch:(UIPinchGestureRecognizer*)recognizer

{

NSLog(@"Pinch %f",recognizer.scale);

CGPoint location=[recognizer locationInView:self.view];

}

在屏幕上用两只手指点击屏幕就会输出以下内容

在屏幕上进行放大缩小的手势时就会输出以下内容

  在实际中往往会出现这么一个情况,一个按钮同时存在着双击和单击操作,单击的时候会触发单击的,双击的时候就只会触发双击的,那这样子就添加两个UITapGestureRecognizer,单击的就把numberOfTapsRequired属性设成1,双击的时候就把numberOfTapsRequired设成2,结果运行的时候发现,单击的能正常单击,双击的时候,既触发了双击的,也触发了单击的。这样子不允许的,手势识别的应该是互斥的,解决这种情况就需要调用[A requireGestureRecognizerToFail:B]方法。代码就修改成如下,点击的时候就要么触发单击的,要么就触发双击的,不会双击和单击的都同时触发

在ViewDidLoad里面添加以下代码

UITapGestureRecognizer* singleRecognizer;

singleRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(SingleTap:)];

singleRecognizer.numberOfTapsRequired = 1; 

[self.view addGestureRecognizer:singleRecognizer];

UITapGestureRecognizer* doubleRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(DoubleTap:)];

doubleRecognizer.numberOfTapsRequired = 2; 

[self.view addGestureRecognizer:doubleRecognizer];

[singleRecognizer requireGestureRecognizerToFail:doubleRecognizer];

在类里面添加以下方法

-(void)SingleTap:(UIPinchGestureRecognizer*)recognizer

{

NSLog(@"SingleTap");

}

-(void)DoubleTap:(UIPinchGestureRecognizer*)recognizer

{

NSLog(@"DoubleTap");

}
时间: 2024-10-16 01:41:14

iOS学习笔记——触控与手势的相关文章

iOS学习笔记—— UItableView 控件的简单使用

UITableView 可以说是iOS开发中最常用的控件,除了游戏之外,几乎所有的应用中独会出现他的身影. 使用UITableView控件需要遵守两种协议 UITableViewDelegate和 UITableViewDataSource. 常用方法如下: 1.返回(每个分区)表单元个数(行数) - (NSInteger) tableView: (UItableView *) tableVIew numberOfRowsInSection: (NSInteger)section 2.返回表单元

iOS学习笔记—— UIPickerView 控件的简单使用

UIPickerView 是iOS常用的控件之一,它通过轮转界面提供一系列多值选项,它向用户展示信息,也能收集用户输入.下面是一个普通的UIPickerView控件. 使用UIPickerView控件需要遵守两种协议,一种是UIPickerViewDelegate,另一种是UIPickerViewDataSource. UIPickerViewDelegate协议的方法有: 1.  -(NSString *) pickerView: (UIPickerView * )pickerView tit

ios 学习笔记之控件属性

1.文本框 设置密码属性:Secure Text Entry 勾选; 设置文本框带清除属性: Clear Button =Is always visible;  默认是不带清除属性:Never appears 设置文本框默认带出文字属性:Placeholder=用户自定义输入; 设置文本框键盘用户输入完成隐藏代码: [self.text resignFirstResponder];//适用于单个文本框输入完成时隐藏 [self.view endEditing:YES];//适用于全部文本框输入完

ios学习笔记图片+图片解释(c语言 oc语言 ios控件 ios小项目 ios小功能 swift都有而且笔记完整喔)

下面是目录其中ios文件夹包括了大部分ios控件的介绍和演示,swift的时完整版,可以学习完swift(这个看的是swift刚出来一周的视频截图,可能有点赶,但是完整),c语言和oc语言的也可以完整的学习完所需知识,,其他文件夹的内容如其名说描述一样 没张图片都有文字说明,可以需要该功能的时候搜索一下然后打开图片就可以学习到 网盘下载地址:需要的话给留言我再传上去 http://www.cnblogs.com/langtianya原创 ios学习笔记图片+图片解释(c语言 oc语言 ios控件

iOS学习笔记(2)— UIView用户事件响应

iOS学习笔记(2)— UIView用户事件响应 UIView除了负责展示内容给用户外还负责响应用户事件.本章主要介绍UIView用户交互相关的属性和方法. 1.交互相关的属性 userInteractionEnabled 默认是YES ,如果设置为NO则不响应用户事件,并且把当前控件从事件队列中删除.也就是说设置了userInterfaceEnabled属性的视图会打断响应者链导致该view的subview都无法响应事件. multipleTouchEnabled  默认是NO,如果设置为YE

IOS学习笔记 -- Modal和Quartz2D

一. Modal1.Modal的默认效果:新控制器从屏幕的最底部往上钻,直到盖住之前的控制器为止;Modal只是改变了View的现实,没有改变rootViewController 2.常用方法1>.以Modal的形式展示控制器- (void)presentViewController:(UIViewController *)viewControllerToPresent animated: (BOOL)flag completion:(void (^)(void))completion2>.关

iOS学习笔记(1)— UIView 渲染和内容管理

iOS学习笔记(1)— UIView 渲染和内容管理 iOS中应用程序基本上都是基于MVC模式开发的.UIView就是模型-视图-控制器中的视图,在iOS终端上看到的.摸到的都是UIView. UIView在屏幕上定义了一个矩形区域和管理区域内容的接口.在运行时,一个视图对象控制该区域的渲染:UIView继承自UIResponder,UIResponder是用来响应事件的类,UIView也具有响应事件的能力.所以说UIView具有三个基本的功能,绘制内容并管理内容的布局,响应用户交互,动画.正是

iOS学习笔记-精华整理

iOS学习笔记总结整理 一.内存管理情况 1- autorelease,当用户的代码在持续运行时,自动释放池是不会被销毁的,这段时间内用户可以安全地使用自动释放的对象.当用户的代码运行告一段 落,开始等待用户的操作,自动释放池就会被释放掉(调用dealloc),池中的对象都会收到一个release,有可能会因此被销毁. 2-成员属性:     readonly:不指定readonly,默认合成getter和setter方法.外界毫不关心的成员,则不要设置任何属性,这样封装能增加代码的独立性和安全

iOS学习笔记(3)— 屏幕旋转

iOS学习笔记(3)— 屏幕旋转 一.屏幕旋转机制: iOS通过加速计判断当前的设备方向和屏幕旋转.当加速计检测到方向变化的时候,屏幕旋转的流程如下: 1.设备旋转时,系统接收到旋转事件. 2.系统将旋转事件通过AppDelegate通知当前的主Window. 3.window通知它的rootViewController. 4.rootViewController判断所支持的旋转方向,完成旋转. iOS系统中屏幕旋转事件没有像触碰事件那样进行hitTest,所以只有rootViewControl