以下是小编精心整理的iOS开发学习之触摸事件和手势识别,本文共6篇,供大家参考借鉴,希望可以帮助到有需要的朋友。本文原稿由网友“昂呜”提供。
篇1:iOS开发学习之触摸事件和手势识别
iOS的输入事件
触摸事件
手势识别
手机摇晃
一、iOS的输入事件
触摸事件(滑动、点击)
运动事件(摇一摇、手机倾斜、行走),不需要人为参与的
远程控制事件(耳机控制手机声音)
1⃣️iOS事件对象都是UIEvent类的实例
UIEvent类对事件类型定义了enum常量:
typedef NS_ENUM(NSInteger, UIEventType){
UIEventTypeTouches,
UIEventTypeMotion,
UIEventRemoteControl,
};
触摸事件必须是继承UIResponser的
二、触摸事件
1⃣️UIView,有4种处理不同的触摸事件
UIView是UIResponder的子类,可以覆盖下列4个方法处理不同的触摸事件,
1. 一根或者多根手指开始触摸屏幕
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
2.一根或者多根手指在屏幕上移动(随着手指的移动,会持续调用该方法)
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
3.一根或者多根手指离开屏幕
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
4.触摸结束前,某个系统事件(例如电话呼入)会打断触摸过程
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
复制代码
#pragma mark - UITouch事件
#pragma mark 触摸开始
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(@“触摸开始”);
for (UITouch *touch in touches) {
NSLog(@“%@”, touch);
}
}
#pragma mark 触摸移动
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(@“触摸移动Touch对象个数:%d”,[touches count]);
// 要移动界面上黄颜色的视图
// 1. 得到当前手指的位置
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInView:self.view];
// 2. 得到上一次手指的位置
CGPoint preLocation = [touch previousLocationInView:self.view];
// 3. 计算两个位置之间的偏移
CGPoint ffset = CGPointMake(location.x - preLocation.x, location.y - preLocation.y);
// 4. 使用计算出来的偏移量,调整视图的位置
[_demoView setCenter:CGPointMake(_demoView.center.x + offset.x, _demoView.center.y + offset.y)];
// 完整的UITouch事件调试方法
NSLog(@“触摸移动”);
for (UITouch *touch in touches) {
NSLog(@“%@”, touch);
}
}
#pragma mark 触摸结束
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
// 完整的UITouch事件调试方法
NSLog(@“触摸完成”);
for (UITouch *touch in touches) {
NSLog(@“%@”, touch);
}
}
#pragma mark 触摸中断
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
// 完整的UITouch事件调试方法
NSLog(@“触摸中断”);
for (UITouch *touch in touches) {
NSLog(@“%@”, touch);
}
}
复制代码
2⃣️触摸事件的处理
如果hit-test视图无法处理事件,则通过响应者链向上传递
1.如果hit-test视图的控制器存在,就传递给控制器;如果控制器不存在,则将其传递给它的父视图
2.如果视图或它的控制器无法处理收到的事件或消息,则将其传递给该视图的父视图
3.每一个在视图继承树中的上层视图如果不能处理收到的事件或消息,则重复上面的步骤1,2
4.在视图继承树的最上层视图,如果也不能处理收到的事件或消息,则其将事件或消息传递给窗口对象进行处理
5. 如果窗口对象也不能进行处理,则其将事件或消息传递给UIApplication对象
6.如果UIApplication也不能处理该事件或消息,则将其丢弃
当用户点击屏幕时,会产生一个UITouch对象传递给UIApplication,然后由window负责查找最适合相应触摸事件的视图对象(hitTest,pointInside)
找到合适的视图之后,Touch方法由对应的视图完成,上级视图不再接管
3⃣️不接受处理事件的三种方法
不接收用户交互:userInteractionEnabled = NO;
隐藏:hidden = YES;
透明:alpha = 0~0.01
三、手势识别
1⃣️iOS目前支持的手势识别(6种)
UITapGestureRecognizer(点按)
UIPinchGestureRecognizer(捏合)
UIPanGestureRecognizer(拖动)
UISwipeGestureRecognizer(轻扫)
UIRotationGestureRecognizer(旋转)
UILongPressGestureRecognizer(长按)
2⃣️手势识别的使用方法(4步)
通常在视图加载的时候定义(UIGestureRecognizer是抽象类,需要实例化使用)
创建手势识别实例
设置手势识别属性,例如手指数量,方向等
将手势识别附加到指定的视图之上
编写手势触发响应方法
3⃣️手势识别的状态(7个)
1. // 没有触摸事件发生,所有手势识别的默认状态
UIGestureRecognizerStatePossible,
// 一个手势已经开始但尚未改变或者完成时
UIGestureRecognizerStateBegan,
// 手势状态改变
UIGestureRecognizerStateChanged,
// 手势完成
UIGestureRecognizerStateEnded,
// 手势取消,恢复至Possible状态
UIGestureRecognizerStateCancelled,
// 手势失败,恢复至Possible状态
UIGestureRecognizerStateFailed,
// 识别到手势识别
UIGestureRecognizerStateRecognized =UIGestureRecognizerStateEnded
2.手势识别的属性
state——手势状态
view——手势发生视图
常用方法
locationInView 获得手势发生对应视图所在位置
复制代码
- (void)viewDidLoad
{
[super viewDidLoad];
/**
1. 演示点按手势
*/
// 根据实例化方法,我们知道:
// 1.有一个处理消息的对象,应该是self
// 2.我们需要定义一个方法,当手势识别检测到的时候,运行
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapAction:)];
// setNumberOfTapsRequired 点按次数
[tap setNumberOfTapsRequired:1];
// setNumberOfTouchesRequired 点按的手指数量
[tap setNumberOfTouchesRequired:1];
// 把手势识别增加到视图上
[self.demoView addGestureRecognizer:tap];
/**
篇2:IOS开发UI篇―手势识别器(拖拽+旋转+缩放)
一、拖拽
示例代码:
复制代码
1 //
2 // YYViewController.m
3 // 06-拖拽事件
4 //
5 // Created by apple on 14-6-19.
6 // Copyright (c) itcase. All rights reserved.
7 //
8
9 #import “YYViewController.h”
10
11 @interface YYViewController
12 @property (strong, nonatomic) IBOutlet UIView *iconView;
13
14 @end
15
16 @implementation YYViewController
17
18 - (void)viewDidLoad
19 {
20 [super viewDidLoad];
21
22 //拖拽事件
23 UIPanGestureRecognizer *pan=[[UIPanGestureRecognizer alloc]init];
24 [self.iconView addGestureRecognizer:pan];
25 [pan addTarget:self action:@selector(panView:)];
26 }
27
28 -(void)panView:(UIPanGestureRecognizer*)pan
29 {
30 //以控制器上的view的左上角为坐标原点
31 CGPoint point=[pan locationInView:pan.view];
32 NSLog(@“拖拽事件”);
33 NSLog(@“获取到的触摸点的位置为:%@”,NSStringFromCGPoint(point));
34
35 CGPoint point1=[pan translationInView:pan.view];
36 NSLog(@“拖拽事件1”);
37 NSLog(@“获取到的触摸点的位置为:%@”,NSStringFromCGPoint(point1));
38
39 //手指拖动,让自定义的view也跟着手指移动
40 CGPoint temp=self.iconView.center;
41 temp.x+=point1.x;
42 temp.y+=point1.y;
43 self.iconView.center=temp;
44
45 //清空
46 [pan setTranslation:CGPointZero inView:pan.view];
47 }
48 @end
复制代码
注意点:1.注意拖拽事件的位移叠加,
注意数学递增性,需要在每次调用完之后进行清空处理。
2.注意获取的点是以手指按下的点为原点的。CGPoint point1=[pan translationInView:pan.view];
//以控制器上的view的左上角为坐标原点 CGPoint point=[pan locationInView:pan.view];
二、旋转
示例代码:
复制代码
1 //
2 // YYViewController.m
3 // 07-旋转
4 //
5 // Created by apple on 14-6-19.
6 // Copyright (c) 20 itcase. All rights reserved.
7 //
8
9 #import “YYViewController.h”
10
11 @interface YYViewController ()
12 @property (weak, nonatomic) IBOutlet UIImageView *iconView;
13
14 @end
15
16 @implementation YYViewController
17
18 - (void)viewDidLoad
19 {
20 [super viewDidLoad];
21
22 //旋转
23 //创建手势识别器(旋转)
24 UIRotationGestureRecognizer *gesture=[[UIRotationGestureRecognizer alloc]init];
25 //添加手势识别器
26 [self.iconView addGestureRecognizer:gesture];
27 //监听
28 [gesture addTarget:self action:@selector(gestureView:)];
29 }
30
31 -(void)gestureView:(UIRotationGestureRecognizer*)gesture
32 {
33
34 //旋转的弧度:gesture.rotation
35 NSLog(@“旋转事件,旋转的弧度为:%1f”,gesture.rotation);
36
37 //让图片跟随手指一起旋转
38 //每次从最初的位置开始
39 // self.iconView.transform=CGAffineTransformMakeRotation(gesture.rotation);
40
41 //在传入的transform的基础上旋转
42 //在之前的基础上,让图片跟随一起旋转(去掉自动布局)
43 //注意问题:以风火轮的速度旋转
44 self.iconView.transform=CGAffineTransformRotate(self.iconView.transform, gesture.rotation);
45 //将旋转的弧度清零
46 //(注意不是将图片旋转的弧度清零,而是将当前手指旋转的弧度清零)
47 gesture.rotation=0;
48 }
49 @end
复制代码
注意点:
1.imageview默认为不可交互的,且不支持多点触控,需要在storyboard中勾选这两项,
2.旋转的度数叠加
3.旋转
将旋转弧度清零之后,每次调用又从零开始。
篇3:IOS 开发学习总结objectivec面向对象之――方法
objective-c 的方法不能独立存在,所有的方法都必须定义在类里,方法在逻辑上,要么属于类,要么属于对象。
方法的所属性
不难发现,方法在语法上和功能上,方法与函数很相似。其实,方法是由传统的函数发展而来的。
objective-c 调用函数时的传参机制和调用方法时的传参机制是一样的,都是值传递,都是传入参数的副本。
方法与传统的函数的显著不同:
在结构化编程语言里,函数是一等公民。整个程序是由一个一个函数组成;
面向对象的语言里,类是一等公民。因此在 OC 里方法不能独立存在,必须属于类或者对象。
由于 objective-c 里的方法不能独立存在,也不能像函数那样独立执行,执行方法时必须使用类或者对象作为调用者。
由上,objective-c 中方法的所属性主要体现在下面的3个方面:
1. 方法不能独立定义,只能在类体里定义。
2. 方法在逻辑上,要么属于类,要么属于对象。
3. objective-c 里的方法不能独立存在,也不能像函数那样独立执行,执行方法时必须使用类或者对象作为调用者。
形参个数可变的方法
如果在定义方法时,在最后一个形参名后增加逗号和三点(,…),就表明该形参可以接受多个参数值。
为了在程序中获取个数可变的形参。需使用如下关键字:
- va_list:这是个用于定义指向可变参数列表的指针变量。
- va_start:这是个函数。指定开始处理可变形参的列表,并让指针变量指向可变形参列表的第一个参数。
- va_end:结束处理可变形参,释放指针变量。
- va_arg:该函数返回指针当前指向的参数的值,并将指针移动到指向下一个参数。
如下示例程序:
头文件:VarArgs.h
#import
实现文件:VarArgs.m
#import VarArgs.h@implementation VarArgs- (void)test:(NSString *) name, ...{ // 使用va_list定义一个argList指针变量,该指针变量指向可变参数列表 va_list argList; // 如果为第一个name参数存在,才需要处理后面的参数 if (name) { // 由于name参数并不在可变参数列表中,因此先处理name参数 NSLog(@%@ , name); // 让argList指向第一个可变参数列表的第一个参数,开始提取可变参数列表的参数 va_start(argList, name); // va_arg用于提取argList指针当前指向的参数,并将指针移动到指向下一个参数 // arg变量用于保存当前获取的参数,如果该参数不为nil,进入循环体 NSString* arg = va_arg(argList, id); while (arg) {// 打印出每一个参数.NSLog(@%@,arg);// 再次提取下一个参数,并将指针移动到指向下一个参数arg = va_arg(argList, id); } // 释放argList指针,结束提取 va_end(argList); }}@endint main(int argc , char * argv[]){ @autoreleasepool{ VarArgs* va = [[VarArgs alloc] init]; [va test:@疯狂iOS讲义 , @疯狂Android讲义, @疯狂Ajax讲义 , nil]; }}
本质上说,这个可变参数也是个类似数组的结构,
最后要指出的是,个数可变的形参只能处于形参列表的最后。即:一个方法中最多只能有一个长度可变的形参。
篇4:IOS 开发学习总结 objectivec面向对象之――类和对象(下)
局部变量和成员变量重名的情况下,局部变量会隐藏成员变量,
为了在方法中强行引用成员变量,可以使用 self 关键字进行区分。
示例代码:
FKWolf.h文件
#import
FKWolf.m 文件
#import FKWolf.h@implementation FKWolf// 定义一个setName:ageAge方法- (void) setName: (NSString*) _name andAge: (int) _age{ // 当局部变量隐藏成员变量时, // 可用self代表调用该方法的对象,这样即可为调用该方法的成员变量赋值了。 self->_name = _name; self->_age = _age;}// 定义一个info方法- (void) info{ NSLog(@我的名字是%@, 年龄是%d岁 , _name , _age);}@endint main(int argc , char * argv[]) { @autoreleasepool{ FKWolf* w = [[FKWolf alloc] init]; [w setName: @灰太狼 andAge:8]; [w info]; }}
篇5:IOS 开发学习总结 objectivec面向对象之――类和对象(下)
当 self 作为对象的默认引用使用时,程序可以像访问普通指针变量一样访问这个 self引用,甚至可以把 self 当成普通方法的返回值。
示例程序:
ReturnSel.m文件
#import
说明:使用 self 作为方法的返回值可以使代码更加简洁,但可能造成实际意义的模糊。
id 类型
id 类型可以代表所有对象的类型。任意类的对象都可赋值给 id 类型的变量。
通过 id 类型的变量来调用方法时,objective-c 将会执行动态绑定。动态绑定:objective-c 将会跟踪对象所属的类,会在运行时判断该对象所属的类,并在运行时确定需要动态调用的方法,而不是在编译时确定要调用的方法。
示例程序:
#import
篇6:IOS 开发学习总结 objectivec面向对象之――成员变量,模拟类变量,单例模式
OC 中变量根据定义位置的不同,可以分为3大类:成员变量,局部变量和全局变量,
之前提到过方法是由函数演化而来的,所以不管是方法中定义的变量,还是函数中定义的变量,都是局部变量。
成员变量及其运行机制
成员变量:指的是在类接口部分或类实现部分定义的变量。
说明:objective-c 的成员变量都是实例变量,并不支持真正的类变量。
实例变量从该类的实例被创建开始起存在,直到系统完全销毁这个实例,实例变量的作用域与对应实例的生存范围相同。实例变量可以理解为实例成员变量,它作为实例的一个成员,与实例共存亡。
只要实例存在,程序就可以访问该实例的实例变量,在程序中访问实例变量的语法:实例->实例变量;
示例程序:
#import
总结说明:成员变量无需显式初始化,只要为一个类定义了实例变量,系统会为实例变量执行默认初始化。基本类型的实例变量默认被初始化为0;指针类型的成员变量默认被初始化为 nil.
从内存存储的角度看,objective-c 的对象与C 的结构体相似。
这里用上面的代码中定义的类创建2个实例。结合示意图来说明 OC 中实例变量的初始化和内存中的运行机制。
// 创建第一个FKPerson对象FKPerson* p1 = [[FKPerson alloc] init];
// 创建第二个FKPerson对象FKPerson* p2 = [[FKPerson alloc] init];
// 分别为两个FKPerson对象的name成员变量赋值 p1->_name = @张三; p2->_name = @孙悟空;
模拟类变量
通过内部局部变量来模拟类变量,
**注意:**static关键字不能修饰成员变量,只能修饰局部变量,全局变量和函数。
为了模拟类变量,可以在类实现部分定义个 static 修饰的全局变量,并提供一个类方法来暴露该全局变量。
示例代码:
头文件:FKUser.h
#import
实现文件:FKUser.m
#import FKUser.hstatic NSString* nation = nil;@implementation FKUser+ (NSString*) nation{ // 返回nation全局变量 return nation;}+ (void) setNation: (NSString*) newNation{ // 对nation全局变量赋值 if(![nation isEqualToString: newNation]) { nation = newNation; }}@endint main(int argc , char * argv[]) { @autoreleasepool{ // 为FKUser的类变量赋值 [FKUser setNation:@中国]; // 访问FKUser的类变量 NSLog(@FKUser的nation类变量为:%@, [FKUser nation]); }}
单例模式
如果一个类始终只能创建一个实例,则这个类称为单例类。
单例类可以通过 static 全局变量来实现,程序考虑定义一个 static全局变量,该变量用于保存已经创建的 singleton 对象——每次程序需要获取该实例的时候,先判断该 static 全局变量是不是为 nil, 如果为 nil,则初始化一个实例并赋值给 static 全局变量。
示例程序:
FKSingleton.h
#import
FKSingleton.m
#import FKSingleton.hstatic id instance = nil;@implementation FKSingleton+ (id) instance{ // 如果instance为nil if(!instance) { // 创建一个Singleton实例,并将该实例赋给instance全局变量 instance = [[super alloc] init]; } return instance;}@endint main(int argc , char * argv[]) { @autoreleasepool{ // 判断两次获取的实例是否相等,程序将会返回1(代表真) NSLog(@%d , [FKSingleton instance] == [FKSingleton instance]); }}
事件/委托机制(event/delegate)(Unity3D开发之十
CISCO学习问题之‘passiveinterface‘命令和路由协议网络知识