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