QQ上黏黏的小红点很好玩有木有,于是自己也想实现一番,看到iOS实现的人比较少,Android的比较多,于是这个就用iOS来实现哈~
效果图:
调试图:
其实从实现来讲,我是先实现第二张图的效果的。
实现思路
1.了解原理,以及如何绘制“黏黏”形状(即绘制两圆加两条贝塞尔曲线)。
2.新建UIView(AZMetaBallCanvas),作为单独画布用来绘制“黏黏”形状,用程序实现算法,并绘制出来。
3.给画布(AZMetaBallCanvas)添加attach:(UIView *)
方法,并添加手势监听,重绘,使得任意 view 都能够被在画布上拥有“黏黏”效果。
4.根据连心线的距离加上判断是否要断开,用户手指离开时也要根据距离来判断是爆炸动画还是回弹动画。
详细过程
首先必须要了解小红点拖拽的过程形状是什么,其实就是类似元球效果(MetaBall)。仔细观察可分析发现,就是两个大小不一样的圆加上两条贝塞尔曲线构成的。
关于算法部分,我已经分解成了另外一篇博文,强烈建议不清楚该形状是怎么画出来的同学先看一下《【算法分析】QQ“一键退朝”之详细计算方法》
1.绘制拖拽
既然怎么求坐标点画出来我们已经知道了,现在就可以去实现了。
首先新建一个“画布”,继承自UIView
//AZMetaBallCanvas.h
@interface AZMetaBallCanvas : UIView
@property(nonatomic,strong) Circle *centerCircle;
@property(nonatomic,strong) Circle *touchCircle;
@end
Circle
为自定义实体类,里面定义了一些圆的基本属性,如圆心坐标、半径等。
为什么要新建一个画布?
因为小红点是能够全屏拖动的,别看QQ上它存在某一行Cell
,但其实你可以把它拉到别的Cell
上去,这就需要给小红点足够的位置来绘制,就干脆新建一个画布专门用来绘制小红点的动作好了。
AZMetaBallCanvas
目前包含两个属性,两个圆,一个中心圆,一个触摸圆,按照需求来看,中心圆应该是位置不变的,触摸圆会跟随手指触摸屏幕的位置而改变,后面需要在两个圆之间画上贝塞尔曲线来构成元球效果。
接下来开始写AZMetaBallCanvas
的实现
//AZMetaBallCanvas.m
#define RADIUS 40.0
@interface AZMetaBallCanvas() {
UIBezierPath *_path;
CGPoint _touchPoint;
}
@end
@implementation AZMetaBallCanvas</