小红点解决方案思路分析

栏目: 编程语言 · IOS · 发布时间: 6年前

内容简介:小红点(消息推送提醒)在现今的各个App中几乎无处不在,特别是内容的更新日渐频繁,大量的小红点被投放在各个业务入口。一般来说,小红点主要有三个应用场景: App有新添加的功能提醒用户使用 某一个已有的模块有功能上的更新 功能有内容的变化或业务上的提醒 常见的比如下图所示的QQ消息提示(红点为消息数目的提示), 朋友圈的新回复,店铺上架新品,最新优惠活动提醒等等。 思路分析 通常情况下,小红点...

小红点(消息推送提醒)在现今的各个App中几乎无处不在,特别是内容的更新日渐频繁,大量的小红点被投放在各个业务入口。一般来说,小红点主要有三个应用场景:

  • App有新添加的功能提醒用户使用
  • 某一个已有的模块有功能上的更新
  • 功能有内容的变化或业务上的提醒

常见的比如下图所示的QQ消息提示(红点为消息数目的提示), 朋友圈的新回复,店铺上架新品,最新优惠活动提醒等等。

小红点解决方案思路分析

思路分析

通常情况下,小红点不是孤立使用的,一项功能或业务的运营涉及多个层级多个入口,所以小红点需要有清晰的路径导向,而且包含路径树的概念,父路径的小红点为子路径小红点的并集。其次就是小红点的具体显示,以及显示的具体样式。因此,总结一下后可以把小红点的功能模块归纳为两大块: 小红点路径监测+事件分发和小红点的UI显示。

小红点路径监测+事件分发

小红点所支持的路径格式设计为root.xx.xx, 小红点原则是父节点的小红点为子节点的小红点并集。root为默认的根路径。如下图所示, root.first为子路径, root.second为同级子路径。在纯红点模式下, root的小红点显示为root.first, root.secondroot.third的并集,同理在数字显示模式下, root的badge数量为root.first, root.secondroot.third的badge数量之和。而root.first的badge数量则又为root.first.firstAroot.first.firstB的和。

 小红点解决方案思路分析

小红点的路径监测则是需要提供类似系统KVO的一个Observer, 用来观察路径所对应的小红点的变化,并且当子路径的红点发生变化是需要逐层分发到每一个父路径。当任意子路径有红点触发事件时,父路径也需显示红点。而当所有子路径的红点事情都清除后,父路径的红点才能清除。

总结一下,小红点路径监测需要实现下面的接口:

第一个接口为某个被监测路径发生红点事件触发后提供block业务处理回调,第二个接口则为当发生事件后,在相应的badgeView上显示小红点UI, 这里传入的badgeView可以是一个button, 也可以是一个tab, 因而应该包括所有广义上的UI控件。

小红点的事件触发和分发则需要实现如下接口:

当App收到服务器推送有新内容更新时,需要对某个路径setBadge, 这边的setBadge会触发上面的observe block的回调。且如果消息为数量类型,比如未读消息时,还需要在setBadge的时候添加count属性。若用户点击了消息或进入了某个小红点提示的入口后,需要清除小红点消息,并且如果Observe的时候绑定了显示小红点的UI控件,也需要清除该控件上的小红点图标。

正常情况下,如果某个路径下面还有子路径有小红点,这个时候对该路径clearBadge是应该不起效果的,合理逻辑应该是当子路径的所有小红点都clear掉了后父路径自动清除。但如果这个情况下需要强制清除父路径红点,则需要在clear方法上加一个是否forced清除的参数。

小红点的UI显示

小红点的UI样式应该包括三种: 小红点, 数字自定义的icon或view. 最基本的小红点主要用在业务入口处,用于内容、功能或动态更新的提醒。数字小红点则一般用来展示未读消息的数量。自定义的icon可以显示比如new, 免费, 热门等活动运营的提示,当然如果需要展示更复杂的UI设计也应该支持自定义view作为badge的功能。

既然可以展示三种样式的小红点UI, 那么就需要有一个优先级排序,结合上面的setBadge接口, 我们可以想到的规则是如果setBadge时没有设置count, 那么默认就是展示小红点, 如果设置了count, 那么就展示数字。另外在展示小红点的情况下,如果用户设置了自定义icon那么就优先展示icon, 按照这个思路,小红点样式的优先级就出来了: 数字的优先级最高,其次是自定义icon, 最后则是默认的圆形小红点。

对于UI, 我们都希望可以定制的,所以对于默认的圆形小红点应该可以调整它的半径,以及展示在控件上相对于右上角的offset, 而对于数字小红点应该可以调整它的字体和文字颜色。另外,如果数字的数值特别大,应该有个最高上限,比如超过99后就显示省略号。按照上面这些思路分析,我们可以得到下面所示的BadgeView接口:

小红点显示接口的调用理论上应该由内部来触发,也就是使用方调用:

之后,

这边所指定需要显示小红点的badgeView上会在小红点模块内部来调用showBadge. 当用户点击了显示小红点的控件后,应该在控件的点击事件里面调用clearBadgeForKeyPath来触发内部调用hideBadge. 简而言之,就是使用方不需要显式的来调用badgeViewshowBadge或者hideBadge. 同理,当使用方调用:

会在内部调用badgeView的showBadgeWithValue. 当然如果使用方需要在某个控件上(e.g. badgeView -> UIButton)显示小红点,但是并不需要与某个路径关联,只是单纯的显示小红点,那应该也需要支持[self.button showBadge]的调用。

支持显示小红点的badgeView应该包括广义上的所有UI控件, iOS这边控件主要有3大种类: a). UIView b). UIBarButtonItem c). UITabBarItem, 所以我们可以对这三种类分别写一个category来创建小红点UI并显示在控件上,当然这三个category必须要conform上面的RJBadgeView Protocol:

接口优化

参照上面的讨论,我们需要对小红点路径进行监控,也就是要observePath, 类似于系统的KVO监测API, 这边会有下面几个需要考虑的问题:

  1. 重复添加已有keyPath的observe
  2. observe之后在observer退出或释放后忘记unobserve
  3. 初始化小红点模块的复杂度和便利度
  4. block回调里面可能的循环引用问题

对于第一个问题,我们创建一个数据结构RJBadgeInfo, 用来存放小红点的相关信息,每次添加observe对info进行比较,如果已有监测则不去做重复添加。

第二个问题可以使用自释放的机制来实现observe的自动移除,这样就需要将badgeController作为观察者的成员变量,当observer释放之后badgeController也会释放,那么我们就在badgeController的 dealloc函数中去做observe的移除操作。使用方则无需关心何时去移除观察者,当然如果确实需要提前移除观察者,也可以调用unobservePath接口。

初始化函数生成badgeController并且以observer的成员变量存在,最简单和便捷的方式就是给所有NSObject对象通过category添加badgeController变量,这样用户无需显式去调用alloc方法,只需要self.badgeController即可动态生成badgeController对象。

在badgeController的get方法里面则是调用RJBadgeController的初始化方法生成对象并赋值给self.badgeController变量:

最后一个循环引用的问题,在badge的block里面用参数observer来代替self, 我们对observer(即self.badgeController的self)进行weak化处理并通过block回调参数传出:

方案实现

理论talk完了,可以show源码了,完整的小红点解决方案实现源码RJBadgeKit已经发布到GitHub, 可以直接通过cocoapods, pod ‘RJBadgeKit’集成使用。我们来看下具体应用示例:

假设我们有个促销页面,该促销有两个商品参与活动,则促销页面的路径可设置为root.promotion,促销页面内两个商品的路径分别设为root.promotion.item1, root.promotion.item2. 现在需要推送小红点消息给用户,在promotion的入口处的button需要显示小红点提示,当用户进入到promotion页面且分别点击了item1和item2后,promotion的小红点提示才消失。

首先我们在RJPromotionViewController里面对promotionButton添加路径的观察者,当该路径被setBadge时候则显示小红点,clearBadge时则隐藏小红点:

当网络请求返回时发现有两个促销数据(注意路径的格式),则调用:

子路径的小红点状态变化会触发父路径observe的block回调,所以上述两行代码执行后promotionButton会触发显示小红点。当然如果希望promotionButton不显示小红点,而是显示具体的促销数量,则可以直接如下调用:

如果promotion item下面还有子路径, 则调用:

在这个情况下,promotionButton上显示的数值(亦即root.promotion路径对应的badge值)为root.promotion.item1和root.promotion.item2及其所有子节点的数值之和。当用户点击查看了item1和item2后,分别调用clearBadeg方法来消除小红点:

这时父节点root.promotion的badge自动clear, promotionButton的小红点会自动隐藏。如果希望在item1被clear后就强制清除root.promotion的badge, 则可以在清除item1后调用:

这样即使子节点的badge尚未全部清除,父节点也会被强制clear.

正常情况下不应该去调用force:YES, 如果非要调用,可能是路径结构设计不合理了

对于小红点的样式, RJBadgeKit可以通过offset来设置显示位置,也可以传入需要展示的自定义红点icon. 如果需要展示的样式非常复杂,那也可以直接传入定制的view用来作为badge展示:

下图为RJBadgeKit所对应的Example运行效果, 更详细的使用示例及所有支持的接口方法和属性设置可以参考Example工程。

 小红点解决方案思路分析
demo.gif

最后再贴一下源码地址: https://github.com/RylanJIN/RJBadgeKit, 在使用中有遇到什么问题或者优化建议欢迎留言PR, 如果RJBadgeKit的实现方案对你有所帮助和启发,也不妨给个Star鼓励下。


以上所述就是小编给大家介绍的《小红点解决方案思路分析》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

渐进增强的Web设计

渐进增强的Web设计

[美] Todd Parker、[英] Patty Toland、[英] Scott Jehl、[法] Maggie Costello Wachs / 牛化成 / 人民邮电出版社 / 2014-1 / 69.00

本书由全球著名Web设计公司Filament集团两位创始人和两位开发主力联手打造,其中Scott Jehl还是jQuery团队成员。四位作者具有多年的网站设计和开发经验,曾为网站、无线设备、Web应用设计过众多高度实用的用户界面,受到了高度赞扬。本书展示了如何利用渐进增强方法开发网站,从而获得最佳用户体验。本书既是理解渐进增强原则和益处的实用指南,也用详细的案例分析,目的是向设计师以及开发人员传授......一起来看看 《渐进增强的Web设计》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具