支持多種形式多種動畫風格的推送小紅點WZLBadge(iOS)

jopen 9年前發布 | 34K 次閱讀 IOS iOS開發 移動開發

概述

今天我們來實現一個在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/機器視覺等領域展開交流!

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!