zoukankan      html  css  js  c++  java
  • 限定pan手势只能在圆内移动view

    限定pan手势只能在圆内移动view

    效果:

    虽然看起来很简单,但实现原理还是稍微有点复杂-_-!!

    核心的地方,就是需要计算pan手势的点与指定点的距离,不能超过这个距离,超过了就让动画还原,很容易理解:)

    //
    //  RootViewController.m
    //  Circle
    //
    //  Copyright (c) 2014年 Y.X. All rights reserved.
    //
    
    #import "RootViewController.h"
    
    @interface RootViewController ()
    
    @end
    
    @implementation RootViewController
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        
        // 限定范围用的layer
        CALayer *circleLayer        = [CALayer layer];
        circleLayer.frame           = (CGRect){CGPointZero, CGSizeMake(250, 250)};
        circleLayer.position        = self.view.center;
        circleLayer.cornerRadius    = 250/2.f;
        circleLayer.opacity         = 0.5f;
        circleLayer.backgroundColor = [UIColor orangeColor].CGColor;
        [self.view.layer addSublayer:circleLayer];
        
        // 移动手势
        UIPanGestureRecognizer *pan = 
            [[UIPanGestureRecognizer alloc] initWithTarget:self
                                                    action:@selector(gestureEvent:)];
        
        //  用于移动用的view
        UIView *move = [[UIView alloc] initWithFrame:(CGRect){CGPointZero, CGSizeMake(50, 50)}];
        move.backgroundColor    = [UIColor cyanColor];
        move.center             = self.view.center;
        move.layer.cornerRadius = 50/2.f;
        [move addGestureRecognizer:pan];
        [self.view addSubview:move];
    }
    
    - (void)gestureEvent:(UIPanGestureRecognizer *)gesture
    {
        // 获取手势坐标点
        CGPoint translation = [gesture translationInView:gesture.view];
        
        // 开始
        if (gesture.state == UIGestureRecognizerStateBegan)
        {
            [UIView animateWithDuration:0.2 animations:^{
                gesture.view.backgroundColor = [UIColor redColor];
            }];
        }
        
        // 状态改变
        if (gesture.state == UIGestureRecognizerStateChanged)
        {
            gesture.view.center = CGPointMake(gesture.view.center.x + translation.x,
                                              gesture.view.center.y + translation.y);
    
            // 计算手势的点与指定坐标的距离
            CGPoint pointA    = gesture.view.center;
            CGPoint pointB    = self.view.center;
            CGFloat distanceX = pointA.x - pointB.x;
            CGFloat distanceY = pointA.y - pointB.y;
            CGFloat distance  = sqrt(distanceX*distanceX + distanceY*distanceY);
            
            // 当距离在125.f以内时的一些操作
            if (distance <= 125.f)
            {
                [gesture setTranslation:CGPointZero
                                 inView:gesture.view];
            }
            else
            {
                // 先关闭手势(不允许用户继续与手势交互)
                gesture.enabled = NO;
                
                [UIView animateWithDuration:0.2f animations:^{
                    gesture.view.center          = self.view.center;
                    gesture.view.backgroundColor = [UIColor cyanColor];
                } completion:^(BOOL finished) {
                    // 动画结束后再次开启手势
                    gesture.enabled = YES;
                }];
            }
        }
        
        // 结束
        if (gesture.state == UIGestureRecognizerStateEnded)
        {
            [UIView animateWithDuration:0.2f animations:^{
                gesture.view.center = self.view.center;
                gesture.view.backgroundColor = [UIColor cyanColor];
            }];
        }
    }
    
    @end

    核心代码处:

    1. 计算坐标值

    2. 距离超出指定范围的时候就必须要关闭pan手势并执行动画,动画结束后再开启pan手势,相当重要哦.

  • 相关阅读:
    死锁
    面试题: JVM的四大引用
    面试题:对象怎么定位
    面试题: Spring框架的好处
    VTK 图形基本操作进阶_表面重建技术(等值面提取)
    VTK 图形基本操作进阶_表面重建技术(三角剖分)
    VTK 图形基本操作进阶_多分辨率策略(模型细化的三种方法)
    VTK 图形基本操作进阶_多分辨率策略(模型抽取的三种方法)
    VTK 图形基本操作进阶_连通区域分析
    VTK 图形基本操作进阶_网格模型的特征边 与 封闭性检测
  • 原文地址:https://www.cnblogs.com/YouXianMing/p/3818244.html
Copyright © 2011-2022 走看看