手势

手势识别介绍


Touch机制实现


touch机制实现(操作复杂)

注:正确的打开方式:手势识别


进行封装



手势识别通过这个类来使用(将手势识别封装,抽象了出来)




UIKIt继承了父类UIGestureRecognizer,实现了很多子类

手势识别步骤



点击手势参数


右侧,(按下,松开)


右侧,移动的时候会一直调changed状态,来电话中断会调用cancelled状态,松开会调用Recognized状态


        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.手势识别实践



如何解决手势冲突



解决手势的优先级问题



gestureB优先级高于gestureA


声明手势优先级可以解决swip和pan的冲突,让swip的优先级高于pan,这样快速向右滑动会触发swip,慢速会触发pan。



1.第一个gesture低于other  2.相反



需要实现delegate


手势响应条件:单一手势如何控制手势精确识别


判断是否从possible转变成recognized(可识别状态)



判断一个手势是否可以进入possible状态,来解决这个问题。




- (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;//回归缩放之前的状态

    }

}


自己手势和控件原生的手势发生冲突解决方案


屏幕左侧进行滑动让当前的页面进行返回


将edgPan的手势优先级高于系统手势的优先级,就可以解决(让自己写的手势响应事件了)
解决scrollview的pan手势和tableview横滑手势冲突问题

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];

}



最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容