支持多种形式多种动画风格的推送小红点WZLBadge(iOS)
概述
今天我们来实现一个在iOS中让人又爱又恨的推送“小红点”WZLBadge。那什么是badge呢?当后台有数据更新需要让用户知道时,在按钮或者其他控件上显示一个“小红点”提醒用户。注意,这里的“小红点”仅仅是泛指,实际的视图可以天马行空,在这个版本中我们先实现以下几种:
- 小红点
- 红底白字“new”
- 红底白字数字
为了让小红点显示后更加醒目,在这个版本中我又实现了三种不同的状态动画(status animation):
- 心脏跳动效果( WBadgeAnimTypeScale )
- 呼吸灯效果( WBadgeAnimTypeBreathe)
- 横向抖动( WBadgeAnimTypeShake)
- 静止状态( WBadgeAnimTypeNone, 默认)
WZLBadge还有以下优点:
- 支持横竖屏
- 支持iOS5~iOS8
- 允许高度定制化,包括“红点”的背景颜色,文字(字体大小、颜色),位置等
我们还是先看两张示例图片吧:
分析
想要使得实现出来的badge接口调用方便,我采用的是对UIView做category的方式,接口统一为实例方法。通过这种方式,可以给任意的UIView及其子类添加badge,而且接口简单。接口应该类似于这样:
[someView showBadgeWithStyle:WBadgeStyleRedDot value:0 animationType:WBadgeAnimTypeShake];
现实往往是这样的,使用者使用起来越简单, 接口提供方就需要做的越多。我们知道,小红点应该具有多个属性,比如大小、背景颜色、文字颜色等。想让badge具有更强的可定制性,就需要开放这些丰富的属 性。那么问题来了,category中理论上只能添加方法,无法添加属性。这时候就需要一些运行时runtime方面的技巧了。我们可以在运行时为UIView添加属性,需要使用到的两个runtime api为:
OBJC_EXPORT id objc_getAssociatedObject(id object, const void *key) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_1);
OBJC_EXPORT void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_1);
例如,假设我们现在想给UIView动态添加badgeBgColor属性,用来操纵badge角标的背景色“
- (UIColor *)badgeBgColor//getter { return objc_getAssociatedObject(self, &badgeBgColorKey); }
- (void)setBadgeBgColor:(UIColor *)badgeBgColor//setter { objc_setAssociatedObject(self, &badgeBgColorKey, badgeBgColor, OBJC_ASSOCIATION_RETAIN); }
关于动态添加属性的知识在这里就不具体展开了,想要了解更多的可以参考我的这篇《 iOS运行时runtime初探(强制获取并修改私有变量,强制增加及修改私有方法等) 》。这个知识点也是本文开源的WZLBadge的核心点,实际上这也是大多数开源工具的常规做法。另外,对于WZLBadge的其他技术细节在这里就不再细述,具体可以到文章末尾处转去Github查看。
使用方法
由于WZLBadge采用对UIView扩展category的方式,因此,所有的UIView及其继承子类(UIControl等)都可以无缝使用,当前版本开放的接口主要有以下几个:
/** * show badge with red dot style and WBadgeAnimTypeNone by default. */ - (void)showBadge;
/** * showBadge * * @param style WBadgeStyle type * @param value (if 'style' is WBadgeStyleRedDot or WBadgeStyleNew, this value will be ignored. In this case, any value will be ok.) * @param aniType */ - (void)showBadgeWithStyle:(WBadgeStyle)style value:(NSInteger)value animationType:(WBadgeAnimType)aniType;
/** * clear badge */ - (void)clearBadge;
源代码分享
我将源代码托管在github上,我个人希望WZLBadge能不断优化成为iOS平台上推送红点的终极解决方案,如果你感兴趣,我非常欢迎你一起加入让WZLBadge变得更好。有什么问题或者建议请留言或者在github提issue。
此外,希望你能在github上对WZLBadge进行star/fork/watch,接下来我的更新会直接通知到你^^。
github地址: WZLBadge (https://github.com/weng1250/WZLBadge)
原创文章,转载请注明 编程小翁@博客园,邮件zilin_weng@163.com,欢迎各位与我在C/C++/Objective-C/机器视觉等领域展开交流!