限定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(, )};
circleLayer.position = self.view.center;
circleLayer.cornerRadius = /.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(, )}];
move.backgroundColor = [UIColor cyanColor];
move.center = self.view.center;
move.layer.cornerRadius = /.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 <= .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手势,相当重要哦.