首页 > 代码库 > 限定pan手势只能在圆内移动view

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