支持多种形式多种动画风格的推送小红点WZLBadge(iOS)

jopen 9年前

概述

今天我们来实现一个在iOS中让人又爱又恨的推送“小红点”WZLBadge。那什么是badge呢?当后台有数据更新需要让用户知道时,在按钮或者其他控件上显示一个“小红点”提醒用户。注意,这里的“小红点”仅仅是泛指,实际的视图可以天马行空,在这个版本中我们先实现以下几种:

  • 小红点
  • 红底白字“new”
  • 红底白字数字

为了让小红点显示后更加醒目,在这个版本中我又实现了三种不同的状态动画(status animation):

  • 心脏跳动效果( WBadgeAnimTypeScale )
  • 呼吸灯效果( WBadgeAnimTypeBreathe)
  • 横向抖动( WBadgeAnimTypeShake)
  • 静止状态( WBadgeAnimTypeNone, 默认)

WZLBadge还有以下优点:

  • 支持横竖屏
  • 支持iOS5~iOS8
  • 允许高度定制化,包括“红点”的背景颜色,文字(字体大小、颜色),位置等

我们还是先看两张示例图片吧:

Github系列之二:开源 支持多种形式多种动画风格的推送小红点WZLBadge(iOS)

分析

想要使得实现出来的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/机器视觉等领域展开交流!