zoukankan      html  css  js  c++  java
  • (转)UIPanGestureRecognizer

    UIPanGestureRecognizer是UIGestureRecognizer类的一个扩展类,其扩展类有UITapGestureRecognizer,UIPinchGestureRecognizer,UIRotationGestureRecognizer,UISwipeGestureRecognizer,UIPanGestureRecognizer,UILongPressGestureRecognizer。

    借助这些类,可以实现UIView对象的一些操作如对象放大缩小,移动,旋转,滑动,轻击等。再也不用去重写UIView的touchBegin等方法来实现这些功能。

    知识点:
    UIGestureRecognizer是一个定义基本手势的抽象类,具体什么手势,在以下子类中包含:
        1、拍击UITapGestureRecognizer (任意次数的拍击)  
        2、向里或向外捏UIPinchGestureRecognizer (用于缩放)  
        3、摇动或者拖拽UIPanGestureRecognizer (拖动) 
        4、擦碰UISwipeGestureRecognizer (以任意方向)  
        5、旋转UIRotationGestureRecognizer (手指朝相反方向移动)  
        6、长按UILongPressGestureRecognizer (长按)

    这些操作的目的都是用来修改UIView对象的frame,center,bounds属性,还有一个Transform属性。

    我写了一个例子,在UIView和UITableView上分别添加UIPanGestureRecognizer,实现两个对象在手指按住对象于屏幕中拖动的效果。

    声明一个UIPanGestureRecognizer对象,添加到UIView对象上去。UIView类有这样的方法用来动态添加和删除UIPanGestureRecognizer对象。

    UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
    [testPanView addGestureRecognizer:panRecognizer];

    UIView管理手势识别器的方法有:
    – addGestureRecognizer:
    – removeGestureRecognizer:
      gestureRecognizers  property
    – gestureRecognizerShouldBegin:


    我在viewDidAppear:方法中,动态添加视图和手势识别器。然后,实现识别器需要操作的两个方法,用来移动视图对象。
    在这两个方法中最终的方法是这个 CGPoint translatedPoint = [recognizer translationInView:self.view];

    每一次拖动操作状态,都会获取到translatedPoint,从开始到结束。它是一个绝对值,可以看着在”self.view“对应的坐标体系中,拖动的视图对象center的移动开始和结束的点差。
    最简单的处理过程是这样:
        CGPoint translatedPoint = [recognizer translationInView:self.view];
        CGFloat x = recognizer.view.center.x + translatedPoint.x;
        CGFloat y = recognizer.view.center.y + translatedPoint.y;
        recognizer.view.center = CGPointMake(x, y);
        [recognizer setTranslation:CGPointMake(0, 0) inView:self.view];

    首先获取到移动点的值,然后算一下视图的center值,相加一下,就得到在self.view坐标体系中,视图该移动到那个center上,一次结束就清零一次。
    因为拖动操作持续进行,所以,这个过程会持续执行。

    稍微复杂点的处理过程,会捕获到拖动开始,移动,结束等几个状态下的translatedPoint的值。然后做一下逻辑处理,如视图不能溢出self.view的坐标系中,如在结束时会根据方向自动滑动到某个位置。可以在handlePan2:方法中找到这些逻辑的实现代码。

        
    - (void)viewDidAppear:(BOOL)animated
    {
        NSLog(@" viewDidAppear is at %@.", [NSDate date]);

        UIImage *image = [UIImage imageNamed:@"5.jpg"];

        testPanView = [[UIView alloc] initWithFrame:CGRectMake(18, 11, 100, 100)];

        UIImageView *imageview = [[UIImageView alloc] initWithFrame:[testPanView frame]];
        [imageview setImage:image];
        [testPanView addSubview:imageview];

        UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
        [panRecognizer setMinimumNumberOfTouches:1];
        [panRecognizer setMaximumNumberOfTouches:1];
        [panRecognizer setDelegate:self];
        [testPanView addGestureRecognizer:panRecognizer];

        [self.view addSubview:testPanView];

        testPanTableView = [[UITableView alloc] initWithFrame:CGRectMake(118, 121, 100, 100) style:UITableViewStylePlain];

        UIPanGestureRecognizer *panRecognizer2 = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan2:)];
        [panRecognizer2 setMinimumNumberOfTouches:1];
        [panRecognizer2 setMaximumNumberOfTouches:1];
        [panRecognizer2 setDelegate:self];
        [testPanTableView addGestureRecognizer:panRecognizer2];

        [self.view addSubview:testPanTableView];
    }

    - (void)handlePan:(UIPanGestureRecognizer *)recognizer
    {
        CGPoint translatedPoint = [recognizer translationInView:self.view];
        NSLog(@"gesture translatedPoint  is %@", NSStringFromCGPoint(translatedPoint));
        CGFloat x = recognizer.view.center.x + translatedPoint.x;
        CGFloat y = recognizer.view.center.y + translatedPoint.y;

        recognizer.view.center = CGPointMake(x, y);

        NSLog(@"pan gesture testPanView moving  is %@,%@", NSStringFromCGPoint(recognizer.view.center), NSStringFromCGRect(recognizer.view.frame));

        [recognizer setTranslation:CGPointMake(0, 0) inView:self.view];
    }



    - (void)handlePan2:(UIPanGestureRecognizer *)recognizer
    {
        // NSLog(@"gesture translatedPoint  xxoo xxoo");
        CGPoint translatedPoint = [recognizer translationInView:self.view];

        if ([(UIPanGestureRecognizer *)recognizer state] == UIGestureRecognizerStateBegan) {
            firstX = recognizer.view.center.x;
            firstY = recognizer.view.center.y;
            NSLog(@"self.view bounds is %@", NSStringFromCGRect(self.view.bounds));
            NSLog(@"pan gesture testPanView begin  is %@,%@", NSStringFromCGPoint([recognizer view].center), NSStringFromCGRect([recognizer view].frame));
        }

        if ([(UIPanGestureRecognizer *)recognizer state] == UIGestureRecognizerStateChanged) {
            CGFloat x = firstX + translatedPoint.x;
            CGFloat y = firstX + translatedPoint.y;

            if (x < recognizer.view.width / 2.0) {
                x = recognizer.view.width / 2.0;
            } else if (x + recognizer.view.width / 2.0 > self.view.width) {
                x = self.view.width - recognizer.view.width / 2.0;
            }

            if (y < recognizer.view.height / 2.0) {
                y = recognizer.view.height / 2.0;
            } else if (y + recognizer.view.height / 2.0 > self.view.height) {
                y = self.view.height - recognizer.view.height / 2.0;
            }

            NSLog(@"gesture translatedPoint moving  is %@", NSStringFromCGPoint(translatedPoint));

            recognizer.view.center = CGPointMake(x, y);
        }

        if (([(UIPanGestureRecognizer *)recognizer state] == UIGestureRecognizerStateEnded) || ([(UIPanGestureRecognizer *)recognizer state] == UIGestureRecognizerStateCancelled)) {
            CGFloat x = recognizer.view.center.x;
            CGFloat y = recognizer.view.center.y;

            if (x > firstX) {
                x = self.view.width - recognizer.view.width / 2.0;
            } else {
                x = recognizer.view.width / 2.0;
            }

            if (y > firstY) {
                y = self.view.height - recognizer.view.height / 2.0;
            } else {
                y = recognizer.view.height / 2.0;
            }

            CGFloat velocityX = (0.2 *[recognizer velocityInView:self.view].x);

            [UIView beginAnimations:nil context:NULL];

            [UIView setAnimationDuration:ABS(velocityX * 0.00002 + 0.2)];

            [UIView setAnimationCurve:UIViewAnimationCurveEaseOut];

            recognizer.view.center = CGPointMake(x, y);

            [UIView commitAnimations];

            NSLog(@"gesture translatedPoint  end is %@", NSStringFromCGPoint(translatedPoint));

            NSLog(@"pan gesture testPanView end  is %@,%@", NSStringFromCGPoint([recognizer view].center), NSStringFromCGRect([recognizer view].frame));
        }
    }

  • 相关阅读:
    python中用exit退出程序
    习题5-2 使用函数求奇数和 (15分)
    习题5-1 符号函数 (10分)
    练习5-3 数字金字塔 (15分)
    练习5-2 找两个数中最大者 (10分)
    练习5-1 求m到n之和 (10分)
    ubuntu使用教程
    图解HTTP 上
    Sublime Text 3 插件
    两千行PHP学习笔记
  • 原文地址:https://www.cnblogs.com/code-changeworld/p/4699192.html
Copyright © 2011-2022 走看看