前言

上一篇把动画的实现步骤大致理清,需要确认小尾巴的绘制区域,关键就是确定4个顶点的位置。大家可以根据需要,选择不同的计算方式。
今天,要实现:

  1. 文字的添加
  2. 尾巴拉长用弧形代替直线

下面是现在的效果图:

文字添加

为了简单,这里对文字的颜色字体等属性不提供接口,而只是在内部设置固定的值;提供一个类方法生成对象。如:

+ (instancetype)zzspringViewWithText:(NSString *)text;

在这个方法里面需要做:

  1. 根据text内容,确定文字绘制的图形区域
  2. 根据文字的绘制区域,确定view对象的bounds
  3. 可能的情况下,限制文字的长度(QQ上消息数最多显示99+)

drawRect中,需要做的事:

  1. 绘制带圆角的view
  2. 绘制文字

如下所示:

//draw corner round rectangle
-(void) p_drawRoundedRectWithContext:(CGContextRef)context withRect:(CGRect)rect
{
CGContextSaveGState(context); CGFloat radius = CGRectGetMaxY(rect)*0.4;
CGFloat puffer = CGRectGetMaxY(rect)*0.10;
CGFloat maxX = CGRectGetMaxX(rect) - puffer;
CGFloat maxY = CGRectGetMaxY(rect) - puffer;
CGFloat minX = CGRectGetMinX(rect) + puffer;
CGFloat minY = CGRectGetMinY(rect) + puffer; CGContextBeginPath(context);
CGContextSetFillColorWithColor(context, [UIColor redColor].CGColor);
CGContextAddArc(context, maxX-radius, minY+radius, radius, M_PI+(M_PI/), , );
CGContextAddArc(context, maxX-radius, maxY-radius, radius, , M_PI/, );
CGContextAddArc(context, minX+radius, maxY-radius, radius, M_PI/, M_PI, );
CGContextAddArc(context, minX+radius, minY+radius, radius, M_PI, M_PI+M_PI/, ); CGContextFillPath(context); CGContextRestoreGState(context); }
-(void) p_drawTextWithContext:(CGContextRef)context
{
NSDictionary *fontAttr = @{
NSFontAttributeName : fontText,
NSForegroundColorAttributeName: [UIColor whiteColor]
};
if (CGSizeEqualToSize(bgTextSize, CGSizeZero))
{
bgTextSize = [self.badgeText sizeWithAttributes:fontAttr];
} CGPoint textPoint = CGPointMake((rect.size.width/-bgTextSize.width/), (rect.size.height/-bgTextSize.height/) - );
self.badgeText drawAtPoint:textPoint withAttributes:fontAttr];
}

draw text && arch rectangle

其中,bgTextSize是之前计算过的文字的size。

弧线

绘制曲线,这里使用CGContextAddQuadCurveToPoint,这里的控制点controlPoint取自两圆心之间的某点(见),这里我取了圆心长度的黄金分割点处作为控制点。从实际的运行情况下,可能弧度不是太明显,需要后期再调配参数。
这里还要纠正一下,上一篇计算切点时的方法有误:

  1. 三角函数忘记开根号
  2. 求切点的公式算错了

这里需要说明的是,因为添加了文字,在这里确定P1圆上2个顶点位置的时候,要注意不要覆盖到文字区域,否则移动的时候,文字会被覆盖。
另外,我发现QQ中,拖拽弹回的动画中,小红点上会出现很多纵横交错的白线(bug吗),估计是用于计算连接点用的。

总结

本身这个动画没有什么技术难度(意思是涉及到的框架内容不实特别复杂),复杂得是一些关键数值的确定:主要就是拖拽时尾巴的绘制区域的确定。把这一部分解决了,动画也就没有实现的难度了。当然,如果要封装成一个库来调用,还需要再精进:接口的设计,可配置的参数(颜色,字体,阴影等),这些就留给大伙自定义吧

 

仿手机QQ消息小红点动画2的更多相关文章

  1. 仿手机iPhone QQ消息小红点动画1

    前言 偶然发现iPhone QQ 显示消息条数的小红点可以响应动作事件,也有人问我这样的动画该怎么做,这里就把实现的思路简单的描述一下.在实现的过程中,同样发现该功能并没有看到的那么简单,要做一个完备 ...

  2. vue-miniQQ——基于Vue2实现的仿手机QQ单页面应用(接入了聊天机器人,能够进行正常对话)

    使用Vue2进行的仿手机QQ的webapp的制作,作品由个人独立开发,源码中进行了详细的注释. 由于自己也是初学Vue2,所以注释写的不够精简,请见谅. 项目地址 https://github.com ...

  3. 高仿手机QQ音乐之——Android带进度条的开关

    最新版的手机QQ音乐体验确实不错,发现首页播放按钮能够显示歌曲当前进度条.认为挺有新意.效果例如以下: 自己琢磨了下.能够用自己定义组件来实现,试着做了一下.效果例如以下: 整理了下思路.大概设计流程 ...

  4. Android之高仿手机QQ聊天

    源代码下载 转载请注明出处,谢谢! 最终版已上传.优化下拉刷新.增加来消息声音提示.主界面改成ViewPager,实现左右滑动.新增群组.最近会话显示条数,开始上班了,不再修改了.谢谢! 国庆这几天, ...

  5. Android:仿手机QQ朋友动态ListView

    1.介绍: 使用此博客XListView模仿Android版本QQ朋友动态ListView效果.效果如下面的截图: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZ ...

  6. Android:仿手机QQ好友动态的ListView

    1.介绍: 本博客使用XListView模仿Android版QQ好友动态的ListView效果.效果截图例如以下: 效果图1 watermark/2/text/aHR0cDovL2Jsb2cuY3Nk ...

  7. 类似QQ消息左滑删除的Demo

    最近在网上学到一篇类似QQ消息左滑删除的demo,完善了下代码,感觉还不错,特此分享一波: CustomSwipeListView.java 是个继承自ListView的类,里面调用了自定义View ...

  8. wpf实现仿qq消息提示框

    原文:wpf实现仿qq消息提示框 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/huangli321456/article/details/5052 ...

  9. js高仿QQ消息列表左滑功能

    该组件,主要功能类似于QQ消息列表左滑出现删除.标为已读等按钮的功能:现在的版本用的是纯javaScript编写:后续会跟进 angularJs 开发的类似组件以及jquery的; 下面,就让我们来认 ...

随机推荐

  1. 008Spring & JPA & Hibernate & MySQL

    01下载免安装版MySQL 02安装MySQL a)将MySQL压缩包解压到合适的位置,以C:\programmer\Tools\mysql-5.7.20-winx64路径为例: b)新建系统变量,变 ...

  2. django项目配置

    创建工程 本项目使用git管理项目代码,代码库放在gitee码云平台.(注意,公司中通常放在gitlab私有服务器中) 1. 在git平台创建工程 1) 创建私有项目库 2)克隆项目到本地 3)创建并 ...

  3. 《SQL必知必会》知识点汇总

    select CustomerNo from dbo.Customers; 通配符的使用 select *from dbo.Customers; select CustomerNo from dbo. ...

  4. WMIC应用

    WMI管理:wmic      product 列出已安装软件 wmic product where name='tools-windows' call Uninstall 卸载已安装软件 进入wmi ...

  5. Javascript 中 true 和 false

    "" == false // true "0" == false // true "" == "0" //false 以 ...

  6. 购买 In-app Billing 商品

    购买 In-app Billing 商品 一旦你的应用连接上了 Google Play,你就可以初始化内购商品的购买请求了.Google Play 提供了结算接口,可以让用户进入使用他们的支付方式,所 ...

  7. C指针和数组

    一.指针 指针就是地址,指针变量是用来存放地址的变量,把谁的地址存放在指针变量中,就说此指针变量指向谁. 二.数组 1.一维数组 一维数组名代表数组首元素的地址,因此 *a=a[0]; &:取 ...

  8. CentOS7使用systemctl添加自定义服务

    一.简介 Centos7开机第一个程序从init完全换成了systemd这种启动方式,同centos 5 6已经是实质差别.systemd是靠管理unit的方式来控制开机服务,开机级别等功能. 在/u ...

  9. 沉淀,再出发:XPath的理解和使用

    沉淀,再出发:XPath的理解和使用 一.前言   在很多查找的场合之下,我们需要使用正则表达式和其他的查找工具来进行内容的匹配和查找,特别是对于xml文件,我们可以使用xpath等工具来进行查找,通 ...

  10. August 31st 2017 Week 35th Thursday

    Whatever happened in the past is gone, the best is always yet to come. 无论过去发生什么,最好的永远尚未到来. Correct j ...