1. 手势
将用户物理性的触屏操作变成对象存储起来,所有手势的父类 UIGestureRecognizer
系统将一些有特点的触屏操作封装成不同的手势类型包括以下几种:
- UITapGestureRecognizer 点击
- UISwipeGestureRecognizer 轻扫
- UILongPressGestureRecognizer 长按
- UIPinchGestureRecognizer 捏合
- UIPanGestureRecognizer 拖拽
- UIRotationGestureRecognizer 旋转
如何使用手势?
- step1:创建指定手势的实例,在创建时设定当该手势发生时,系统会自动发什么消息
- step2.设置手势的核心属性
- step3.将手势添加到某个视图中,当用户在该视图上做了相应的动作,就会触发手势,系统会捕获并调用手势的事件方法
a.Taps手势
- 核心属性
- numberOfTapsRequired
- numberOfTouchesRequired
- (void)viewDidLoad {
[super viewDidLoad];
//1.创建手势对象
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tap:)];
//2.设置手势的核心属性
tap.numberOfTapsRequired = 5; //点几次
tap.numberOfTouchesRequired = 1; //几个触摸点
//3.将手势添加到某个视图中,当用户在该视图上做了相应的动作,就会触发手势,系统会捕获并调用手势的事件方法
[self.myView addGestureRecognizer:tap];
}
-(void)tap:(UITapGestureRecognizer*)gr {
NSLog(@"点击手势触发,点中的位置是 %@", NSStringFromCGPoint([gr locationInView:self.myView]));
}
b.Swipe 手势 (轻扫)
- 核心属性
- direction 方向
- (void)viewDidLoad {
[super viewDidLoad];
UISwipeGestureRecognizer *swipe = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipe:)];
//上下左右 只 触发 左右
swipe.direction = UISwipeGestureRecognizerDirectionLeft | UISwipeGestureRecognizerDirectionRight | UISwipeGestureRecognizerDirectionUp | UISwipeGestureRecognizerDirectionDown;
[self.view addGestureRecognizer:swipe];
}
-(void)swipe:(UISwipeGestureRecognizer*)gr {
NSLog(@"清扫方向 %lu", gr.direction);
//结束父视图编辑 收键盘
[self.view endEditing:YES];
}
上面两个手势 都是 一次性手势,即手势发生过程中,响应方法只执行依次
c. UILongPress 手势 长按
- 核心属性
- minimumPressDuration 长按所需最小时间
- (void)viewDidLoad {
[super viewDidLoad];
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(longPress:)];
//设置长按触发最小时间
longPress.minimumPressDuration = 2;
[self.view addGestureRecognizer:longPress];
}
-(void)longPress:(UILongPressGestureRecognizer*)gr {
NSLog(@"%@", NSStringFromCGPoint([gr locationInView:self.view]));
if (gr.state == UIGestureRecognizerStateBegan) {
NSLog(@"开始长按");
}else if(gr.state == UIGestureRecognizerStateChanged) {
NSLog(@"移动");
}else if(gr.state == UIGestureRecognizerStateEnded) {
NSLog(@"长按手势结束");
}
}
d. UIPan 手势 拖拽
三种拖拽方式
- (void)viewDidLoad {
[super viewDidLoad];
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(pan:)];
[self.view addGestureRecognizer:pan];
}
-(void)pan:(UIPanGestureRecognizer*)gr {
NSLog(@"1--%@",NSStringFromCGPoint([gr locationInView:self.view]));
NSLog(@"2--%@",NSStringFromCGPoint([gr translationInView:self.view]));
//方式一
if (gr.state == UIGestureRecognizerStateBegan) {
self.startPos = self.imageView.center;
}else {
CGPoint translation = [gr translationInView:self.view];
CGPoint center = self.imageView.center;
center.x = self.startPos.x + translation.x;
center.y = self.startPos.y + translation.y;
self.imageView.center = center;
}
//方式二
// CGPoint translation = [gr translationInView:self.view];
// CGPoint center = self.imageView.center;
// center.x += translation.x;
// center.y += translation.y;
// self.imageView.center = center;
// [gr setTranslation:CGPointZero inView:self.view];
//方式三
// if (gr.state == UIGestureRecognizerStateBegan) {
// //手势开始时 记录 起始位置
// self.startPos = [gr locationInView:self.view];
// }else if (gr.state == UIGestureRecognizerStateChanged){
// //获取本次 移动的位置
// CGPoint move = [gr locationInView:self.view];
// //图片的位置的等于当前位置 加上 移动位置-上次位置 的 偏移
// CGPoint center = self.imageView.center;
// center.x += move.x - self.startPos.x;
// center.y += move.y - self.startPos.y;
// self.imageView.center = center;
// //设置本次位置 为下次的 起始位置
// self.startPos = move;
// }
}
e. UIPich 手势 捏合
- (void)viewDidLoad {
[super viewDidLoad];
UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc]initWithTarget:self action:@selector(pinch:)];
[self.view addGestureRecognizer:pinch];
}
-(void)pinch:(UIPinchGestureRecognizer*)gr {
NSLog(@"速率 %.2f",gr.velocity);
NSLog(@"缩放比 %.2f",gr.scale);
}
f. UIRotation 手势 旋转
- (void)viewDidLoad {
[super viewDidLoad];
UIRotationGestureRecognizer *rotation = [[UIRotationGestureRecognizer alloc]initWithTarget:self action:@selector(rotation:)];
[self.view addGestureRecognizer:rotation];
}
-(void)rotation:(UIRotationGestureRecognizer*)gr {
NSLog(@"%.2f",gr.rotation);
}
2.变形 (transform)
- 什么是变形
- 视图发生了 位移, 缩放, 旋转这样的变化叫做变形
- 如何实现视图的变形
- 通过修改视图对象 transform属性就能完成变形
- transform属性
- 类型 CGAffineTransform (结构体类型)
- 修改transform
- translation 位移
- scale 缩放
- rotation 旋转
- CGAffineTransformMakeTranslation
- CGAffineTransformTranslate
- CGAffineTransformMakeScale
- CGAffineTransformScale
- CGAffineTransformMakeRotation
- CGAffineTransformRotate
- 清除视图的所有变形
- CGAffineTransformIdentity
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
//位移变化
//CGAffineTransformMakeTranslation 变形是基于变形前的那个基础状态
// self.imageView.transform = CGAffineTransformMakeTranslation(50, 50);
//变形是在 当前 变形基础上 继续变形
self.imageView.transform = CGAffineTransformTranslate(self.imageView.transform, 50, 50);
//缩放变形
// self.imageView.transform = CGAffineTransformMakeScale(1.1, 1.5);
self.imageView.transform = CGAffineTransformScale(self.imageView.transform, 1.02, 1.02);
//旋转变化
// self.imageView.transform = CGAffineTransformMakeRotation(M_PI_4);
self.imageView.transform = CGAffineTransformRotate(self.imageView.transform, M_PI_4);
NSLog(@"transform %@",NSStringFromCGAffineTransform(self.imageView.transform));
}
- (IBAction)resetTranform:(id)sender {
// CGAffineTransformIdentity 是个常量, 用该常量给 transform属性赋值 会 清空 transform 的所有变形
self.imageView.transform = CGAffineTransformIdentity;
NSLog(@"transform %@",NSStringFromCGAffineTransform(self.imageView.transform));
}
手势加变形综合应用
多手势同时出发必须使用 UIGestureRecognizerDelegate 代理
//手势代理方法 返回YES是可以同时触发
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return YES;
}
- (void)viewDidLoad {
[super viewDidLoad];
//拖拽
UIPanGestureRecognizer *panGR = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(panGR:)];
self.imageView.userInteractionEnabled = YES;//imageView默认关闭用户交互
[self.view addGestureRecognizer:panGR];
//捏合
UIPinchGestureRecognizer *pinchGR = [[UIPinchGestureRecognizer alloc]initWithTarget:self action:@selector(pinchGR:)];
pinchGR.delegate = self;
[self.view addGestureRecognizer:pinchGR];
//旋转
UIRotationGestureRecognizer *rotationGR = [[UIRotationGestureRecognizer alloc]initWithTarget:self action:@selector(rotationGR:)];
rotationGR.delegate = self;
[self.view addGestureRecognizer:rotationGR];
//点击
UITapGestureRecognizer *tapGR = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapGR:)];
[self.view addGestureRecognizer:tapGR];
}
-(void)tapGR:(UITapGestureRecognizer*)gr {
self.imageView.transform = CGAffineTransformIdentity;
}
-(void)rotationGR:(UIRotationGestureRecognizer*)gr {
CGFloat rotation = gr.rotation;
self.imageView.transform = CGAffineTransformRotate(self.imageView.transform, rotation);
gr.rotation = 0;
}
-(void)pinchGR:(UIPinchGestureRecognizer*)gr {
CGFloat scale = gr.scale;
self.imageView.transform = CGAffineTransformScale(self.imageView.transform, scale, scale);
gr.scale = 1;
}
-(void)panGR:(UIPanGestureRecognizer*)gr {
// CGPoint translation = [gr translationInView:self.view];
// CGPoint center = self.imageView.center;
// center.x += translation.x;
// center.y += translation.y;
// self.imageView.center = center;
// [gr setTranslation:CGPointZero inView:self.view];
CGPoint translation = [gr translationInView:self.view];
self.imageView.transform = CGAffineTransformTranslate(self.imageView.transform, translation.x, translation.y);
[gr setTranslation:CGPointZero inView:self.view];
}
3.深入坐标系 (frame bounds center transform)
1.frame
- 类型:CGRect类型
- 作用:定位—视图的左顶点在父视图坐标系中的对应的点的坐标,以及视图在父视图中占据了多大的空间
2.bounds
- 类型:CGRect类型
- 作用:描述了视图自身的坐标系的顶点的值,以及视图自身的尺寸大小
3.center
- 类型:CGPoint类型
- 作用:描述了视图中心点在父视图坐标系下的位置
4.transform
- 类型:CGAffineTransform 类型
作用:描述视图的变形状态
通过更改bounds实现scroll滑动效果
//手势的事件方法
- (IBAction)panMove:(UIPanGestureRecognizer*)sender {
CGPoint move = [sender translationInView:self.view];
CGRect bounds = self.myView.bounds;
if (move.y < 0) { //向上拖拽
//bounds 应该越来越大
bounds.origin.y += -move.y;
}else if (move.y > 0) { //向下拖拽
//bounds 应该越来越小
bounds.origin.y -= move.y;
}
self.myView.bounds = bounds;
[sender setTranslation:CGPointZero inView:self.view];
}
———————————————————————————————
- | frame | bounds | center | transform |
---|---|---|---|---|
frame | 变 | 圆点不变 | 宽高会变 | 变 |
bounds | 圆点不变 宽高会变 | 变 | 不变 | 不变 |
center | 变 | 不变 | 变 | 不变 |
transform | 不变 | 不变 | 不变 | 变 |
———————————————————————————————