展示效果
實(shí)現(xiàn)思路
- 2個(gè)圓(一個(gè)是固定圓衔蹲,一個(gè)是可拖動(dòng)的圓)
- 貝塞爾畫(huà)形狀
- 拖動(dòng)的時(shí)候固定圓的比例是縮小的
- 到一定距離的時(shí)候會(huì)斷開(kāi)
- 松開(kāi)手勢(shì)就會(huì)回彈到原地
事前準(zhǔn)備工作
@property (nonatomic, strong) UIView *view1;
@property (nonatomic, strong) UIView *view2;
@property (nonatomic, strong) CAShapeLayer *shapeLayer;
@property (nonatomic, assign) CGPoint oldViewCenter;
@property (nonatomic, assign) CGRect oldViewFram;
@property (nonatomic, assign) CGFloat r1;
- (void)setup{
UIView *view1 = [[UIView alloc] initWithFrame:CGRectMake(CGRectGetWidth(self.view.bounds) / 2, CGRectGetHeight(self.view.bounds) * 1/9, 40, 40)];
view1.backgroundColor = [UIColor redColor];
view1.layer.cornerRadius = 20;
_view1 = view1;
[self.view addSubview:view1];
UIView *view2 = [[UIView alloc] initWithFrame:_view1.frame];
view2.backgroundColor = [UIColor redColor];
view2.layer.cornerRadius = 20;
_view2 = view2;
[self.view addSubview:view2];
//添加label
UILabel *numL = [[UILabel alloc] initWithFrame:_view2.bounds];
numL.text = @"66";
numL.textAlignment = NSTextAlignmentCenter;
numL.textColor = [UIColor whiteColor];
[_view2 addSubview:numL];
//添加手勢(shì)
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panAction:)];
[_view2 addGestureRecognizer:pan];
//實(shí)例化CAShapeLayer
_shapeLayer = [CAShapeLayer layer];
_shapeLayer.fillColor = [UIColor redColor].CGColor;
// [self.view.layer addSublayer:_shapeLayer];
_oldViewFram = _view1.frame;
_oldViewCenter = _view1.center;
_r1 = CGRectGetWidth(_view1.frame)/2;
}
- 需要保存原先中心點(diǎn)的位置
- 需要保存原先圓的大小,因?yàn)樵跀嚅_(kāi)的時(shí)候需要回到原來(lái)的樣子
- shapeLayer 是直接初始化添加呈础,在拖拽中改變path就可以了
-
根據(jù)手勢(shì)判斷處理移動(dòng)View屬性狀態(tài)
- (void)panAction:(UIPanGestureRecognizer *)ges{
if (ges.state == UIGestureRecognizerStateChanged) {
//view2跟著移動(dòng)
_view2.center = [ges locationInView:self.view];
//
if (_r1 < wift
_view1.hidden = YES;
[_shapeLayer removeFromSuperlayer];
}else{
//計(jì)算出6個(gè)關(guān)鍵點(diǎn)舆驶,然后畫(huà)貝塞爾曲線
[self caculPoint];
}
}else if (ges.state == UIGestureRecognizerStateFailed || ges.state == UIGestureRecognizerStateEnded || ges.state == UIGestureRecognizerStateCancelled){
[_shapeLayer removeFromSuperlayer];
[UIView animateWithDuration:.5 delay:0 usingSpringWithDamping:.3 initialSpringVelocity:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
_view2.center = _oldViewCenter;
} completion:^(BOOL finished) {
_view1.hidden = NO;
_r1 = _oldViewFram.size.width/2;
_view1.frame = _oldViewFram;
_view1.layer.cornerRadius = _r1;
}];
}
}
- 因?yàn)樵诮Y(jié)束動(dòng)畫(huà)之后會(huì)需要很多點(diǎn)的復(fù)原問(wèn)題,所以我們?cè)陂_(kāi)始的時(shí)候就需要記錄
- [_shapeLayer removeFromSuperlayer]; 在取消和結(jié)束的時(shí)候還是需要移除layer的
不然會(huì)出現(xiàn)畫(huà)的紅色背景還在的情況
- usingSpringWithDamping 彈簧阻力效果
-
計(jì)算拖拽中的關(guān)鍵點(diǎn)
- (void)caculPoint{
//1.求出2個(gè)中心點(diǎn)
CGPoint center1 = _view1.center;
CGPoint center2 = _view2.center;
//2.計(jì)算2個(gè)中心點(diǎn)的距離
CGFloat dis = sqrtf((center1.x - center2.x)*(center1.x - center2.x) + (center1.y - center2.y)*(center1.y - center2.y));
//3.計(jì)算正弦余弦
CGFloat sin = (center2.x - center1.x) / dis;
CGFloat cos = (center1.y - center2.y) / dis;
//4.計(jì)算半徑
CGFloat r1 = CGRectGetWidth(_oldViewFram)/2 - dis/20;
CGFloat r2 = CGRectGetWidth(_view2.bounds)/2;
_r1 = r1;
NSLog(@"%f",r1);
//5.計(jì)算6個(gè)關(guān)鍵點(diǎn)
CGPoint pA = CGPointMake(center1.x - cos*r1, center1.y - sin*r1);
CGPoint pB = CGPointMake(center1.x + cos*r1, center1.y + sin*r1);
CGPoint pD = CGPointMake(center2.x - cos*r2, center2.y - sin*r2);
CGPoint pC = CGPointMake(center2.x + cos*r2, center2.y + sin*r2);
CGPoint pP = CGPointMake(pB.x + dis/2*sin, pB.y - dis/2*cos);
CGPoint pO = CGPointMake(pA.x + dis/2*sin, pA.y - dis/2*cos);
//6.畫(huà)貝塞爾曲線
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:pA];
[path addQuadCurveToPoint:pD controlPoint:pO];
[path addLineToPoint:pC];
[path addQuadCurveToPoint:pB controlPoint:pP];
[path closePath];
//7.修改_shapeLayer的path
_shapeLayer.path = path.CGPath;
[self.view.layer insertSublayer:_shapeLayer below:_view2.layer];
//8.重新設(shè)置view的大小
_view1.center = _oldViewCenter;
_view1.bounds = CGRectMake(0, 0, _r1*2, _r1*2);
_view1.layer.cornerRadius = _r1;
}
- CGRectGetWidth(_oldViewFram)/2 - dis/20; 這里再次設(shè)置寬度的時(shí)候需要用到原先的那個(gè)值而钞,不然r1的值就會(huì)有問(wèn)題
6個(gè)關(guān)鍵點(diǎn)計(jì)算說(shuō)明(ABCDOP)