支持多種形式多種動畫風格的推送小紅點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/機器視覺等領域展開交流!