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