限定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手势,相当重要哦.

 

 

 

 

 

限定pan手势只能在圆内移动view,,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。