手势识别介绍
注:正确的打开方式:手势识别
手势识别步骤
UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];
[_testView addGestureRecognizer:panGesture];
- (void)pan:(UIPanGestureRecognizer *)gesture
{
CGPointtranslatePoint = [gesturetranslationInView:self.view];
_testView.center = CGPointMake(_testView.center.x + translatePoint.x, _testView.center.y + translatePoint.y);//计算的距离会从初始位置开始算起,所以移动的距离会变大,只有重置这个才行
[gesturesetTranslation:CGPointZero inView:self.view];//重置这个偏移量
if (gesture.state == UIGestureRecognizerStatePossible)
{
NSLog(@"possible");
}
else if (gesture.state == UIGestureRecognizerStateBegan)
{
NSLog(@"began");
}
else if (gesture.state == UIGestureRecognizerStateChanged)
{
NSLog(@"changed");
}
else if (gesture.state == UIGestureRecognizerStateEnded)
{
NSLog(@"ended");
}
}
1.手势识别实践
声明手势优先级可以解决swip和pan的冲突,让swip的优先级高于pan,这样快速向右滑动会触发swip,慢速会触发pan。
手势响应条件:单一手势如何控制手势精确识别
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer*)gestureRecognizer
{
if(gestureRecognizer ==_tap)
{
CGPointlocation = [gestureRecognizer locationInView:_superView];
if (CGRectContainsPoint(_subView.frame, location))
{
return NO;//不触发手势
}
return YES;
}
return YES;
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer*)gestureRecognizer shouldReceiveTouch:(UITouch*)touch
{
if(gestureRecognizer ==_tap)
{
if (touch.view != _superView && [touch.view isDescendantOfView:_superView])
{
returnNO;
}
returnYES;
}
return YES;
}
多手势同时响应
#import "GestureSimultaneousViewController.h" //边拉伸,边放大缩小
@interface GestureSimultaneousViewController()
{
UIView*_view;
UIPinchGestureRecognizer *_pinch;
UIRotationGestureRecognizer *_rotation;
}
@end
@implementationGestureSimultaneousViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
self.edgesForExtendedLayout = UIRectEdgeNone;
_view = [[UIView alloc] init];
_view.backgroundColor = [UIColor orangeColor];
_view.frame=CGRectMake(50, 50, 150, 150);
[self.view addSubview:_view];
_rotation = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotate:)];//以弧度旋转
_rotation.delegate = self;
[self.view addGestureRecognizer:_rotation];
_pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinch:)];//相对于触摸的缩放比例
_pinch.delegate = self;
[self.view addGestureRecognizer:_pinch];
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer*)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer*)otherGestureRecognizer
{
return YES;//允许多个手势共同触发
}
- (void)rotate:(UIRotationGestureRecognizer *)gesture
{
if (gesture.state == UIGestureRecognizerStateChanged)
{
_view.transform = CGAffineTransformRotate(_view.transform, gesture.rotation);
[gesturesetRotation:0];//回到原点
}
}
- (void)pinch:(UIPinchGestureRecognizer *)gesture
{
if (gesture.state == UIGestureRecognizerStateChanged)
{
_view.transform = CGAffineTransformScale(_view.transform, gesture.scale, gesture.scale);
gesture.scale= 1;//回归缩放之前的状态
}
}
自己手势和控件原生的手势发生冲突解决方案
1.定义一个scrollview的子类,原因:scrollview的pan手势不允许更改
@interface TestScrollView : UIScrollView
@end
@implementation TestScrollView
- (BOOL)gestureRecognizer:(UIGestureRecognizer*)gestureRecognizer shouldReceiveTouch:(UITouch*)touch
{
if ([NSStringFromClass([touch.view class]) isEqualToString:@"UITableViewCellContentView"])
{
returnNO;//如果是tableview的cell的话不触发UIScrollview的pan手势
}
return YES;
}
@interface GestureSystemViewController()
{
//demo5.1
UIView*_testView;
UIScreenEdgePanGestureRecognizer *_edgePan;
//demo5.2
// UIScrollView *_scrollView;
TestScrollView*_scrollView;
UITableView*_tableView;
}
@end
@implementationGestureSystemViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
self.edgesForExtendedLayout = UIRectEdgeNone;
//demo5.1
_testView = [[UIView alloc] init];
_testView.backgroundColor = [UIColor orangeColor];
_testView.frame=CGRectMake(50, 50, 150, 150);
[self.view addSubview:_testView];
_edgePan = [[UIScreenEdgePanGestureRecognizer alloc] initWithTarget:self action:@selector(edgePan:)];
_edgePan.edges = UIRectEdgeLeft;
[self.view addGestureRecognizer:_edgePan];
[self.navigationController.interactivePopGestureRecognizer requireGestureRecognizerToFail:_edgePan];
//demo5.2
// _scrollView = [[UIScrollView alloc] init];
_scrollView = [[TestScrollView alloc] init];
_scrollView.backgroundColor = [UIColor lightGrayColor];
_scrollView.frame=CGRectMake(50, 250, 300, 300);
_scrollView.contentSize = CGSizeMake(1000, 300);
[self.view addSubview:_scrollView];
_tableView = [[UITableView alloc] init];
_tableView.backgroundColor = [UIColor whiteColor];
_tableView.delegate = self;
_tableView.dataSource = self;
_tableView.frame=CGRectMake(0, 10, 300, 280);
[_scrollView addSubview:_tableView];
}
#pragma mark - pan
- (void)edgePan:(UIScreenEdgePanGestureRecognizer *)gesture
{
if (gesture.state == UIGestureRecognizerStateChanged)
{
CGPointtranslatePoint = [gesturetranslationInView:self.view];
_testView.center = CGPointMake(_testView.center.x + translatePoint.x, _testView.center.y);
[gesturesetTranslation:CGPointZero inView:self.view];
}
else if (gesture.state == UIGestureRecognizerStateEnded)
{
_testView.frame=CGRectMake(50, 50, 150, 150);
}
}
#pragma mark - tableview
- (NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section
{
return10;
}
- (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
NSString*identifier =@"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if(!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
}
cell.textLabel.text = [NSString stringWithFormat:@"cell %zd", indexPath.row];
returncell;
}
- (BOOL)tableView:(UITableView*)tableView canEditRowAtIndexPath:(NSIndexPath*)indexPath
{
return YES;
}
- (void)tableView:(UITableView*)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath*)indexPath
{
}
自定义手势
三指滑屏的demo,判断逻辑在touchbegin、touchmoved里面,除了这里面的其他的都是准备工作。
#import "CustomGestureRecognizer.h" 自定义的手势,三指demo
#import
#import
@interfaceUITouch(BeginPoint)
@property(nonatomic,assign)CGPointtestCustomTouchBeginPoint;//保存手势开始滑动的时候的起点坐标
@end
@implementationUITouch(BeginPoint)
- (void)setTestCustomTouchBeginPoint:(CGPoint)testCustomTouchBeginPoint
{
NSString*string =NSStringFromCGPoint(testCustomTouchBeginPoint);
objc_setAssociatedObject(self, @"testCustomTouchBeginPoint", string, OBJC_ASSOCIATION_RETAIN_NONATOMIC);//将传入的point进行保存
}
- (CGPoint)testCustomTouchBeginPoint
{
NSString *string = objc_getAssociatedObject(self, @"testCustomTouchBeginPoint");
if(!string) {
return CGPointZero;
}
CGPoint point = CGPointFromString(string); //将string转回point
return point;
}
@end
@implementationCustomGestureRecognizer
{
id_testTarget;
SEL_testAction;
}
- (instancetype)initWithTarget:(id)target action:(SEL)action
{
self= [superinitWithTarget:targetaction:action];
if(self)
{
_testTarget= target;
_testAction= action;
}
return self;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent*)event
{
for(UITouch*touchintouches) {
touch.testCustomTouchBeginPoint = [touch locationInView:self.view];//记录每个touch在view当中的坐标
}
[supertouchesBegan:toucheswithEvent:event];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent*)event
{
if(touches.count== 3)//检测是否是三指移动,然后出发响应的action
{
BOOLallTestPass =YES;
for(UITouch*touch in touches)//遍历touchs,//x或者y移动都要超过100才能响应这个action
{
CGPointcurrentPoint = [touchlocationInView:self.view];
CGFloattouchMovedY = currentPoint.y- touch.testCustomTouchBeginPoint.y;
CGFloattouchMovedX = currentPoint.x- touch.testCustomTouchBeginPoint.x;
if(!(ABS(touchMovedX) > 100 ||ABS(touchMovedY) > 100))
{
allTestPass =NO;
break;
}
}
if(allTestPass)
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored"-Warc-performSelector-leaks"
if ([_testTarget respondsToSelector:_testAction])
{
[_testTarget performSelector:_testAction withObject:self];
}
#pragma clang diagnostic pop
} }
[supertouchesMoved:toucheswithEvent:event];
}
#import "CustomGestureViewController.h"
#import "CustomGestureRecognizer.h"
@implementationCustomGestureViewController //使用自定义的三指滑动手势
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
self.edgesForExtendedLayout = UIRectEdgeNone;
CustomGestureRecognizer *gesture = [[CustomGestureRecognizer alloc] initWithTarget:self action:@selector(customGesture:)];
[self.view addGestureRecognizer:gesture];
}
- (void)customGesture:(CustomGestureRecognizer*)gesture
{
[self alertMessage:@"custom gesture!!"];
}
- (void)alertMessage:(NSString*)message
{
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"" message:message preferredStyle:UIAlertControllerStyleAlert];
[alertaddAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]];
[self presentViewController:alert animated:YES completion:nil];
}