前言:
談到APP里面群頭像功能的實(shí)現(xiàn),很容易想到獲取展示位數(shù)頭像稚茅,并根據(jù)UI繪制圖片纸淮。從開(kāi)發(fā)角度上講,為了更好實(shí)現(xiàn)這個(gè)功能亚享,還需要考慮緩存咽块,占位,以及線程和圖片的繪制欺税。為了可以更優(yōu)雅的實(shí)現(xiàn)這個(gè)功能和減少侵入性侈沪,我設(shè)計(jì)了這個(gè)框架。并希望能讓群頭像的實(shí)現(xiàn)盡可能的能像SDWebImage
加載一張圖片那么簡(jiǎn)單晚凿。
接下來(lái)我會(huì)結(jié)合Demo來(lái)談?wù)勥@個(gè)框架的設(shè)計(jì)亭罪。
CDDGroupAvatar框架:
- 1:使用
- 2:設(shè)計(jì)初衷
- 3:實(shí)現(xiàn)分析
- 4:緩存與更新機(jī)制
- 5:集成方式
- 6:不足或后續(xù)優(yōu)化
一.使用
為什么要把使用放在第一個(gè)來(lái)講,因?yàn)槲蚁胝宫F(xiàn)出CDDGroupAvatar
的簡(jiǎn)單和方便歼秽,由于功能自身的難度性并不是很大应役,如果封裝出來(lái)的輪子還是很繁瑣,那還不如自己寫(xiě)個(gè)方法類(lèi)來(lái)的輕巧燥筷。
1:調(diào)用
[self.avImageViewW8 dc_setImageAvatarWithGroupId:@"avImageViewW8" Source:_groupNum8];
分類(lèi)方法調(diào)用傳入群頭像id和群頭像數(shù)據(jù)源數(shù)組箩祥,完事!
來(lái)看看展示
2:肆氓?不對(duì)還缺點(diǎn)什么
在CDDGroupAvatar中提供了DCAvatarManager
類(lèi)滥比。可以統(tǒng)一設(shè)置做院,baseURL盲泛、頭像類(lèi)型、占位圖等等键耕。這些屬性都或多或少的可以幫助你簡(jiǎn)化調(diào)用寺滚。一般來(lái)說(shuō)加載頭像后臺(tái)返回的數(shù)據(jù)是xxxx.jpg/.png,并不是一個(gè)完整的頭像地址需要我們自行去拼接屈雄,baseUrl屬性就可以很好地處理村视,在初始化的時(shí)候設(shè)置好統(tǒng)一的拼接頭,接下來(lái)你只需這樣酒奶。
// 初始化
[DCAvatarManager sharedAvatar].baseUrl = @"http://xxxxxx";
// 數(shù)組的格式
_groupNum2 = @[@"006tNc79gy1g56or92vvmj30u00u048a.jpg",@"006tNc79gy1g56mcmorgrj30rk0nm0ze.jpg"];
// 加載頭像
baseUrl + _groupNum2[index]
不用擔(dān)心不同拼接頭的情況蚁孔,頭像本身就是一個(gè)完整的鏈接的話,默認(rèn)就不會(huì)再拼接baseUrl屬性惋嚎。
下面還有一些其他的參數(shù)
#pragma mark - DCAvatarManager屬性
/* 請(qǐng)求的baseURL杠氢。這應(yīng)該只包含URL的共體部分,例如http://www.example.com另伍。 */
@property (strong , nonatomic)NSString *baseUrl;
/* 頭像類(lèi)型枚舉(默認(rèn)微信樣式) */
@property (assign , nonatomic) DCGroupAvatarType groupAvatarType;
/* 頭像背景(默認(rèn)微信背景色) */
@property (nonatomic, strong) UIColor *avatarBgColor;
/* 一次性設(shè)置小頭像加載失敗的占位圖 : 權(quán)重低于類(lèi)方法中的placeholder屬性 placeholderImage < (id)placeholder */
@property (nonatomic, strong) UIImage *placeholderImage;
/* 微信和QQ群內(nèi)小頭像間距(默認(rèn)值:2) */
@property (nonatomic, assign) CGFloat distanceBetweenAvatar;
/* 微博外邊圈寬度(默認(rèn):10) */
@property (nonatomic, assign) CGFloat bordWidth;
#pragma mark - SDWebImage依賴框架屬性
/* sd加載群內(nèi)單個(gè)小圖片屬性 (默認(rèn):SDWebImageRetryFailed | SDWebImageLowPriority ) */
@property (assign , nonatomic) SDWebImageOptions sdImageOptions;
3:如果你不想設(shè)置統(tǒng)一的占位圖鼻百,例如根據(jù)性別顯示不同占位你也可以這樣
placeholder:占位圖屬性 你可像這樣去傳值@[@"p1",@"p2"] 或者 @[image1,image2] 當(dāng)然@[@"p1",image2]也行。在框架內(nèi)部會(huì)在合適的位置顯示。
// 傳入無(wú)效地址測(cè)試 Placeholder屬性
[self.avImageViewW2 dc_setImageAvatarWithGroupId:@"avImageViewW2" Source:@[@"1",@"2"] itemPlaceholder:@[@"man",@"woman"] options:0 completed:nil];
注温艇!權(quán)重大于 統(tǒng)一設(shè)置的placeholderImage屬性
4:可選和回調(diào)
就像圖片加載框架SDWebImage
一樣我同樣提供了加載可選和數(shù)據(jù)的回調(diào)因悲,方便使用者自行選擇。
CDDGroupAvatar提供兩種加載模式DCGroupAvatarCacheType
:
- DCGroupAvatarCachedDefault (默認(rèn)) : 走緩存 取到返回 沒(méi)有則獲取最新
- DCGroupAvatarCachedRefresh : 先讀緩存再獲取最新
[self.avImageViewW4 dc_setImageAvatarWithGroupId:@"avImageViewW4" Source:_groupNum4 itemPlaceholder:@"place" options:DCGroupAvatarCachedRefresh completed:nil];
CDDGroupAvatar提供GroupImageBlock
回調(diào):
[self.avImageViewW9 dc_setImageAvatarWithGroupId:@"avImageViewW9" Source:_groupNum9 completed:^(NSString *groupId, UIImage *groupImage, NSArray<UIImage *> *itemImageArray, NSString *cacheId) {
NSLog(@"groupId:%@ -- 群頭像:%@ 群內(nèi)拼接小頭像數(shù)組:%@ -- cacheId:%@",groupId, groupImage, itemImageArray , cacheId);
}];
5:同樣CDDGroupAvatar
也支持Button勺爱,調(diào)用方式和ImageView一樣晃琳,還可以根據(jù)UIControlState屬性去展示。
// Image
[self.avaButton dc_setImageAvatarWithGroupId:@"avaButton" Source:_groupNum9 forState:0];
// Background
[self.avaBgButton dc_setBackgroundImageAvatarWithGroupId:@"avaBgButton" Source:_groupNum4 forState:0];
6:支持什么格式的群頭像
目前CDDGroupAvatar
支持三種樣式的群頭像:微信(默認(rèn))琐鲁、QQ蝎土、微博,你可以通過(guò)groupAvatarType
去選擇
來(lái)張全家福:
二:設(shè)計(jì)初衷:
為了減少浸入性绣否,功能內(nèi)聚誊涯,可以使群頭像的實(shí)現(xiàn)盡可能的能像SDWebImage
加載一張圖片那么簡(jiǎn)單。同時(shí)更進(jìn)一步的去學(xué)習(xí)SDWebImage的源碼蒜撮。
三:微信樣式分析:
接下來(lái)暴构,我以微信樣式分析一下整個(gè)框架的運(yùn)行流程
在如上流程中,主要有圖片的批量下載段磨,尺寸和位置計(jì)算取逾,圖片的繪制,裁剪苹支,緩存和回調(diào)處理砾隅,以及如何優(yōu)雅的兼顧Image和Button的調(diào)用。特別是一開(kāi)始cache為空的時(shí)候批量加載群內(nèi)成員的頭像和完成后回調(diào)债蜜,以及這個(gè)過(guò)程中占位圖和緩存的處理晴埂,還要有一些挑戰(zhàn)的。
從上面最全的一張展示圖來(lái)看寻定,微信和QQ這兩種群頭像圖片的繪制還不算難儒洛,中規(guī)中矩,計(jì)算好小頭像的大小狼速,和位置繪制琅锻。在設(shè)計(jì)過(guò)程中,微博樣式稍微讓我有些頭疼向胡。
1:在拿到群內(nèi)所有成員頭像后恼蓬,首先需要先確定的就是小頭像的尺寸
2:其次是確定每個(gè)頭像所在的位置(x,y)坐標(biāo)
3:根據(jù)他們的frame進(jìn)行群頭像的繪制
4:圖片的屬性處理
為了避免繪制的圖片和地址圖片的屬性不等,我在等圖片繪制成功后會(huì)有一次關(guān)于圖片屬性的調(diào)整僵芹,默認(rèn)以群成員地址加載出來(lái)的屬性為準(zhǔn)处硬。
5:緩存和回調(diào)
在批量加載圖片的的統(tǒng)一回調(diào)中我新增了一個(gè)屬性BOOL succeed
,加載的成功性淮捆。用來(lái)判斷是否進(jìn)行存儲(chǔ)郁油。如果群內(nèi)的所有頭像都加載失敗,那就不用存儲(chǔ)了攀痊,直接返回上次的緩存圖片或者默認(rèn)占位圖片桐腌。這樣既可以避免重復(fù)存儲(chǔ),也能一定意義上的優(yōu)化顯示苟径。
四.緩存與更新機(jī)制
說(shuō)到緩存案站,這是在網(wǎng)絡(luò)加載過(guò)程中必不可少的一步,針對(duì)繪制成功的群頭像會(huì)做一次緩存和磁盤(pán)的存儲(chǔ)棘街。緩存方面利用的事 SDWebImage 框架中的Cache蟆盐。既然 SDWebImage 本身的加載就自帶緩存,為什么還需要再做一遍呢遭殉?節(jié)約性能這樣可以避免重復(fù)計(jì)算和繪制石挂。重復(fù)的計(jì)算和繪制都是會(huì)損耗一定的性能。
緩存key是如何定義的险污?又如何能保證及時(shí)更新痹愚?
CDDGroupAvatar 中的cacheId是一段字符屬性的拼接然后進(jìn)行MD5。其中以群頭像id蛔糯,群內(nèi)頭像的數(shù)量(以最大截取數(shù))拯腮,群頭像數(shù)據(jù)源的最后一個(gè)對(duì)象(監(jiān)聽(tīng)變動(dòng)),和一些邊距蚁飒,背景顏色等屬性進(jìn)行拼接动壤。
id%@_num%zd_lastObj%@_distance%.f_bordWidth%.f_bgColor%@
這樣可以在兼顧群內(nèi)成員變動(dòng),主題切換淮逻,甚至自定義邊距改變的同時(shí)能后及時(shí)的對(duì)已經(jīng)繪制的好的緩存中群頭像進(jìn)行更新琼懊。
五.Demo的演示
clean操作:清除所有內(nèi)存緩存和磁盤(pán)緩存
如上截圖中的樣式在demo演示項(xiàng)目中均有實(shí)現(xiàn)。
六.集成方式
- CocoaPods
1:在 Podfile 中添加 pod 'CDDGroupAvatar
'爬早,執(zhí)行 pod install 或 pod update肩碟。
- 手動(dòng)導(dǎo)入
1:將demo項(xiàng)目中的 CDDGroupAvatar
文件夾所有內(nèi)容拖入你的工程中。
2:集成 SDWebImage
框架凸椿。
- 用法
1:導(dǎo)入#import <CDDGroupAvatar/DCAvatar.h>
可以擁有全部功能削祈。
2:調(diào)用對(duì)應(yīng)控件的類(lèi)方法。
3:如果有使用上的疑問(wèn)脑漫,可以下載演示demo進(jìn)行查看髓抑。
七.不足或后續(xù)優(yōu)化
1:項(xiàng)目重度依賴SDWebImage
框架。不管是圖片的加載和緩存都是用的此框架优幸,為什么不去減少對(duì)外部框架的自己實(shí)現(xiàn)吨拍,成本太高,簡(jiǎn)易的自己去實(shí)現(xiàn)一個(gè)加載圖片和緩存功能网杆,還不見(jiàn)得能比依賴此框架來(lái)的好羹饰。
2:微博類(lèi)型的繪制模式不夠完美伊滋。后續(xù)有需要我會(huì)把此類(lèi)型的實(shí)現(xiàn)拿出來(lái)分析,就目前而言我覺(jué)得現(xiàn)在的處理方式不夠好队秩,有優(yōu)化的空間笑旺。特別是在相交的處理方式上,我更愿意一次繪制的時(shí)候設(shè)置相切路徑馍资。
后續(xù):我重點(diǎn)會(huì)把第二個(gè)優(yōu)化一下筒主。
最后還是建議有需要去下載源碼。如果有覺(jué)得處理不當(dāng)?shù)牡胤侥裥罚€望大家能多多指點(diǎn)我乌妙,更好去完善它。
工具:
在設(shè)計(jì)demo和測(cè)試的過(guò)程中用到如下兩款工具:
iPic - Markdown 圖床建钥、文件上傳工具藤韵,一個(gè)很方便的軟件一直在使用,非常推薦熊经,App Store就可以下載還是免費(fèi)的
JPFPSStatus:記錄當(dāng)前屏幕的幀數(shù)(FPS)荠察,joggerplus大神的開(kāi)源,GitHub就有源碼奈搜,集成和使用非常方便悉盆。
參考:
地址:
Github:CDDGroupAvatar
Follow:RocketsChen · GitHub
版本更新 - 1.5.2:
支持脫敏SDWebImage
框架,詳情查看