效果
思路:
代码
#import "ViewController.h"
/*
拆分动画:
1.2个圆(一个固定圆,一个拖拽圆) (完成!)
2.贝塞尔曲线,求得关键点 (完成!)
3.固定圆的比例缩小
4.拖拽到一定距离则需要断开
5.断开之后有一个反弹的动画效果
*/
@interface ViewController ()
//圆1
@property (nonatomic, strong) UIView *view1;
//圆2
@property (nonatomic, strong) UIView *view2;
//shapeLayer图层
@property (nonatomic, strong) CAShapeLayer *shapeLayer;
//坐标记录
@property (nonatomic, assign) CGPoint oldViewCenter;
@property (nonatomic, assign) CGRect oldViewFrame;
@property (nonatomic, assign) CGFloat r1;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//1.UI.
[self setUp];
}
-(void)setUp
{
//1.view1
_view1 = [[UIView alloc]initWithFrame:CGRectMake(36, CGRectGetHeight(self.view.bounds)-66, 40, 40)];
_view1.layer.cornerRadius = 20;
_view1.backgroundColor = [UIColor redColor];
[self.view addSubview:_view1];
//2.view2
_view2 = [[UIView alloc]initWithFrame:CGRectMake(36, CGRectGetHeight(self.view.bounds)-66, 40, 40)];
_view2.layer.cornerRadius = 20;
_view2.backgroundColor = [UIColor redColor];
[self.view addSubview:_view2];
//3.提示数
UILabel *label = [[UILabel alloc]initWithFrame:_view2.bounds];
label.text = @"99";
label.textAlignment = NSTextAlignmentCenter;
label.textColor = [UIColor whiteColor];
[_view2 addSubview:label];
//4.添加手势
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(panAction:)];
[_view2 addGestureRecognizer:pan];
_shapeLayer = [[CAShapeLayer alloc]init];
_oldViewFrame = _view1.frame;
_oldViewCenter = _view1.center;
_r1 = CGRectGetWidth(_view1.frame)/2;
}
-(void)panAction:(UIPanGestureRecognizer *)pan{
if (pan.state == UIGestureRecognizerStateChanged) {
//_view2.跟着你手指移动
_view2.center = [pan locationInView:self.view];
//当我们拖拽到一定距离,则移除
if (_r1 < 9) {
_view1.hidden = YES;
[_shapeLayer removeFromSuperlayer];
}
[self caculPoint];
}else if(pan.state == UIGestureRecognizerStateEnded || pan.state == UIGestureRecognizerStateFailed || pan.state == UIGestureRecognizerStateCancelled)
{
//回弹!
//_view2.位置恢复! shaperLayer消失!
//[_shapeLayer removeFromSuperlayer];
//_view2.center = _oldViewCenter;
[_shapeLayer removeFromSuperlayer];
__weak typeof(self) weakSelf = self;
[UIView animateWithDuration:0.5 delay:0 usingSpringWithDamping:0.3 initialSpringVelocity:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
weakSelf.view2.center = weakSelf.oldViewCenter;
} completion:^(BOOL finished) {
weakSelf.view1.hidden = NO;
weakSelf.view1.frame = weakSelf.oldViewFrame;
weakSelf.r1 = weakSelf.oldViewFrame.size.width/2;
weakSelf.view1.layer.cornerRadius = weakSelf.r1;
}];
}
}
-(void)caculPoint{
//1已知条件: 圆1/2的中心点,斜边d,半径r1,r2;
CGPoint center1 = _view1.center;
CGPoint center2 = _view2.center;
//2.斜边
//d = sqrtf((x2-x1)•(x2-x1)+(y1-y2)•(y1-y2));
float dis = sqrtf(pow(center2.x - center1.x, 2)+pow(center1.y - center2.y, 2));
//3.正弦/余弦值.
float sinValue = (center2.x - center1.x)/dis;
float cosValue = (center1.y - center2.y)/dis;
//4.半径
float r1 = CGRectGetWidth(_oldViewFrame)/2 - dis/20;
float r2 = CGRectGetWidth(_view2.frame)/2;
_r1 = r1;
//5.求ABCDOP 6个点!
CGPoint pointA = CGPointMake(center1.x - r1*cosValue, center1.y - r1*sinValue);
CGPoint pointB = CGPointMake(center1.x + r1*cosValue, center1.y + r1*sinValue);
CGPoint pointC = CGPointMake(center2.x + r2*cosValue, center2.y + r1*sinValue);
CGPoint pointD = CGPointMake(center2.x - r1*cosValue, center2.y - r2*sinValue);
CGPoint pointO = CGPointMake(pointA.x+dis/2*sinValue, pointA.y-dis/2*cosValue);
CGPoint pointP = CGPointMake(pointB.x+dis/2*sinValue, pointB.y-dis/2*cosValue);
//6.绘制贝塞尔曲线
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:pointA];
[path addQuadCurveToPoint:pointD controlPoint:pointO];
[path addLineToPoint:pointC];
[path addQuadCurveToPoint:pointB controlPoint:pointP];
[path closePath];
if (_view1.hidden) {
return;
}
_shapeLayer.path = path.CGPath;
_shapeLayer.fillColor = [UIColor redColor].CGColor;
[self.view.layer insertSublayer:_shapeLayer below:_view2.layer];
_view1.center = _oldViewCenter;
_view1.bounds = CGRectMake(0, 0, r1*2, r1*2);
_view1.layer.cornerRadius = r1;
}