在ios中,触摸表示当用户手指触击屏幕及在屏幕上移动时,系统不断发送给应用程序的对象。一个UITouch 对象表示一个触摸,一个UIEvent对象表示一个事件。
例如:捏合手势有两个触摸,两个手指在屏幕上以相反的方向相对的方向,同时也有一个手指操作的简单手势,例如:单击,双击,拖动和滑动,应用程序也有可能处理复杂的手势。
手势是指从一个或多个手指接触屏幕开始,直到手指离开屏幕为止发生的所有事情。 手势是触摸事件的集合。
iOS 系统在 3.2 以后,他提供了一些常用的手势(UIGestureRecognizer 的子类),开发者可以直接使用他们进行手势操作。
• UIPanGestureRecognizer(拖动)
• UIPinchGestureRecognizer(捏合)
• UIRotationGestureRecognizer(旋转)
• UITapGestureRecognizer(点按)
• UILongPressGestureRecognizer(长按)
• UISwipeGestureRecognizer(轻扫)
另外,可以通过继承 UIGestureRecognizer 类,实现自定义手势(手势识别器类)。
手势状态枚举如下:
typedef NS_ENUM(NSInteger, UIGestureRecognizerState) {
UIGestureRecognizerStatePossible, // 尚未识别是何种手势操作(但可能已经触发了触摸事件),默认状态
UIGestureRecognizerStateBegan, // 手势已经开始,此时已经被识别,但是这个过程中可能发生变化,手势操作尚未完成
UIGestureRecognizerStateChanged, // 手势状态发生转变
UIGestureRecognizerStateEnded, // 手势识别操作完成(此时已经松开手指)
UIGestureRecognizerStateCancelled, // 手势被取消,恢复到默认状态
UIGestureRecognizerStateFailed, // 手势识别失败,恢复到默认状态
UIGestureRecognizerStateRecognized = UIGestureRecognizerStateEnded // 手势识别完成,同UIGestureRecognizerStateEnded
};
• 单击(Tap)点击作为最常用手势
• 拖动(Drag)
• 滑动(Flick)
• 横扫(Swipe)
• 双击(Double Tap)
• 放大(Pinch)
• 缩小(Pinch)
• 长按(Touch Hold)
父类手势 UIGestureRecognizer
初始化方法:
- (instancetype)initWithTarget:(nullable id)target action:(nullable SEL)action NS_DESIGNATED_INITIALIZER;
给手势添加事件和移除事件
- (void)addTarget:(id)target action:(SEL)action;
- (void)removeTarget:(nullable id)target action:(nullable SEL)action;
可以通过 locationInView: 获取操作到的点
- (void)rightSwipeGesture:(UISwipeGestureRecognizer *)sender {
// 获取手势操作到的点
CGPoint point = [sender locationInView:self.view];
// 进行判断 是否在指定区域内操作手势
if (CGRectContainsPoint(CGRectMake(0, 0, self.view.frame.size.width/5, self.view.frame.size.height), point))
{
// 在指定区域内做你想做的事
self.hiddenEnable = YES;
self.showSlider(YES);
}
}
UITouch类中包含如下成员函数:
- (CGPoint)locationInView:(UIView *)view:函数返回一个CGPoint类型的值,表示触摸在view这个视图上的位置,这里返回的位置是针对view的坐标系的。调用时传入的view参数为空的话,返回的时触摸点在整个窗口的位置。
CGRectContainsPoint :一个点是否包含在矩形中
Demo 如下:
import "ViewController.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIView *alertView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
/*
UIGestureRecognizer
父类手势带给的东西
初始化方法:
- (instancetype)initWithTarget:(nullable id)target action:(nullable SEL)action NS_DESIGNATED_INITIALIZER;
给手势添加事件和移除事件
- (void)addTarget:(id)target action:(SEL)action;
- (void)removeTarget:(nullable id)target action:(nullable SEL)action;
*/
//添加单击手势
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(sigleTapAction:)];
[self.view addGestureRecognizer:singleTap];
//双击
UITapGestureRecognizer *doubelTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(doubelTapAction:)];
doubelTap.numberOfTapsRequired = 2;
[self.view addGestureRecognizer:doubelTap];
//父类提供的方法:单击要执行必须双击失效
[singleTap requireGestureRecognizerToFail:doubelTap];
// 长按手势
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressAction:)];
[_alertView addGestureRecognizer:longPress];
//捏合手势
UIPinchGestureRecognizer *pinchGesture = [[UIPinchGestureRecognizer alloc]initWithTarget:self action:@selector(pinchAction:)];
[_alertView addGestureRecognizer:pinchGesture];
//拖拽
UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panAction:)];
[_alertView addGestureRecognizer:panGesture];
//旋转
UIRotationGestureRecognizer *rotationGesture = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotationAction:)];
[_alertView addGestureRecognizer:rotationGesture];
//捏合,旋转要失效
[pinchGesture requireGestureRecognizerToFail:rotationGesture];
//左横扫
UISwipeGestureRecognizer *leftSwipeGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeAction:)];
leftSwipeGesture.direction = UISwipeGestureRecognizerDirectionLeft;
[self.view addGestureRecognizer:leftSwipeGesture];
//右横扫
UISwipeGestureRecognizer *rightSwipeGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeAction:)];
rightSwipeGesture.direction = UISwipeGestureRecognizerDirectionRight;
[self.view addGestureRecognizer:rightSwipeGesture];
//上横扫
UISwipeGestureRecognizer *upSwipeGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeAction:)];
upSwipeGesture.direction = UISwipeGestureRecognizerDirectionUp;
[self.view addGestureRecognizer:upSwipeGesture];
//下横扫
UISwipeGestureRecognizer *downSwipeGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeAction:)];
downSwipeGesture.direction = UISwipeGestureRecognizerDirectionDown;
[self.view addGestureRecognizer:downSwipeGesture];
}
//单击
-(void)sigleTapAction:(UITapGestureRecognizer *)sender{
NSLog(@"你单击了我!");
//改变背景颜色
if (sender.view.backgroundColor == [UIColor whiteColor]) {
sender.view.backgroundColor = [UIColor blackColor];
}else{
sender.view.backgroundColor = [UIColor whiteColor];
}
}
//双击
-(void)doubelTapAction:(UITapGestureRecognizer *)sender{
NSLog(@"双击");
}
//长按
-(void)longPressAction:(UILongPressGestureRecognizer *)sender{
NSLog(@"长按");
//长按结束出现提示框
if (sender.state == UIGestureRecognizerStateEnded) {
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"标题" message:@"选择图片" preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction *pAction = [ UIAlertAction actionWithTitle:@"相机" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nullable action){
NSLog(@"调用本地相机");
}];
[alertController addAction:pAction];
UIAlertAction *photoAction = [ UIAlertAction actionWithTitle:@"相册" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nullable action){
NSLog(@"调用本地相册");
}];
[alertController addAction:photoAction];
UIAlertAction *cancelAction = [ UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nullable action){
NSLog(@"cancel");
}];
[alertController addAction:cancelAction];
[self presentViewController:alertController animated:YES completion:nil];
}
}
//缩放
-(void)pinchAction:(UIPinchGestureRecognizer *)sender{
sender.view.transform = CGAffineTransformMakeScale(sender.scale, sender.scale);
}
//拖拽
-(void)panAction:(UIPanGestureRecognizer *)sender{
/********** 拖拽方式一:中心拖拽 *******************
//当你的状态不等于结束状态 不等以失败状态
if (sender.state != UIGestureRecognizerStateEnded && sender.state != UIGestureRecognizerStateFailed) {
CGPoint location = [sender locationInView:sender.view.superview];
sender.view.center = location;
}
*/
/********** 拖拽方式二:一点点的拖拽 ******************
//当手势按在视图上面的点,转为父系坐标 //拿到中心点
CGPoint translatedPoint = [sender translationInView:self.view];
CGFloat firstX;
CGFloat firstY;
if([sender state] == UIGestureRecognizerStateBegan) {
firstX = [sender.view center].x;
firstY = [sender.view center].y;
translatedPoint = CGPointMake(firstX+translatedPoint.x, firstY+translatedPoint.y);
[sender.view setCenter:translatedPoint];
}
*/
/********** 拖拽方式三:带惯性的拖拽,向拖拽方向滑动 ******************/
//视图前置操作
[sender.view.superview bringSubviewToFront:sender.view];
CGPoint center = sender.view.center;
CGFloat cornerRadius = sender.view.frame.size.width / 2;
CGPoint translation = [sender translationInView:self.view];
//NSLog(@"%@", NSStringFromCGPoint(translation));
sender.view.center = CGPointMake(center.x + translation.x, center.y + translation.y);
//防止抖动
[sender setTranslation:CGPointZero inView:self.view];
//动画效果
if (sender.state == UIGestureRecognizerStateEnded) {
//计算速度向量的长度,当他小于200时,滑行会很短
CGPoint velocity = [sender velocityInView:self.view];
CGFloat magnitude = sqrtf((velocity.x * velocity.x) + (velocity.y * velocity.y));
CGFloat slideMult = magnitude / 200;
//NSLog(@"magnitude: %f, slideMult: %f", magnitude, slideMult); //e.g. 397.973175, slideMult: 1.989866
//基于速度和速度因素计算一个终点
float slideFactor = 0.1 * slideMult;
CGPoint finalPoint = CGPointMake(center.x + (velocity.x * slideFactor),
center.y + (velocity.y * slideFactor));
//限制最小[cornerRadius]和最大边界值[self.view.bounds.size.width - cornerRadius],以免拖动出屏幕界限
finalPoint.x = MIN(MAX(finalPoint.x, cornerRadius),self.view.bounds.size.width - cornerRadius);
finalPoint.y = MIN(MAX(finalPoint.y, cornerRadius),self.view.bounds.size.height - cornerRadius);
//使用 UIView 动画使 view 滑行到终点
[UIView animateWithDuration:slideFactor*2 delay:0 options:UIViewAnimationOptionCurveEaseOut
animations:^{
sender.view.center = finalPoint;
}
completion:nil];
}
}
//旋转
-(void)rotationAction:(UIRotationGestureRecognizer *)sender{
sender.view.transform = CGAffineTransformRotate(sender.view.transform, sender.rotation);
sender.rotation = 0.0;
}
//横扫
-(void)swipeAction:(UISwipeGestureRecognizer *)sender{
switch (sender.direction) {
//手势向下滑动
case UISwipeGestureRecognizerDirectionDown:{
//创建CATransition 对象
CATransition *animation=[CATransition animation];
animation.delegate=self; //动画代理
animation.duration=1.0f; //动画持续时间
animation.timingFunction=UIViewAnimationCurveEaseInOut; //速度控制函数,控制动画运行的节奏
animation.type=kCATransitionMoveIn; //设置运动type
animation.subtype=kCATransitionFromBottom; //视图向下滑动
[sender.view.layer addAnimation:animation forKey:@"move in"];
}
break;
//向上滑动
case UISwipeGestureRecognizerDirectionUp:{
CATransition *animation = [CATransition animation];
animation.delegate = self;
animation.duration = 1.0f;
animation.timingFunction = UIViewAnimationCurveEaseInOut;
animation.type = kCATransitionMoveIn;
animation.subtype = kCATransitionFromTop;
[sender.view.layer addAnimation:animation forKey:@"move in"];
}
break;
//向左
case UISwipeGestureRecognizerDirectionLeft:{
CATransition *animation = [CATransition animation];
animation.delegate = self;
animation.duration = 1.0f;
animation.timingFunction = UIViewAnimationCurveEaseInOut;
animation.type = kCATransitionMoveIn;
animation.subtype = kCATransitionFromRight;
[sender.view.layer addAnimation:animation forKey:@"move in"];
}
break;
//向右横扫
case UISwipeGestureRecognizerDirectionRight:{
CATransition *animation = [CATransition animation];
animation.delegate = self;
animation.duration = 1.0f;
animation.timingFunction = UIViewAnimationCurveEaseInOut;
animation.type = kCATransitionMoveIn;
animation.subtype = kCATransitionFromLeft;
[sender.view.layer addAnimation:animation forKey:@"move in"];
}
break;
default:
break;
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
第二次编辑 2017年 3月 3日