iOS中如何優雅的添加圓角和邊框?


  因為項目需要,整理了下圓角和邊框輔助類。想起前幾天標哥還在微博里問圓角在tableView里卡頓的問題,想着去炫耀下。去到標哥的博客,發現已經有一定程度解決給出開源庫並且在推廣,迭代了好幾個版本了。。

  圓角這東西被無數性能追求者津津樂道,無數小白們高山仰止。 至於圓角的幾種實現方案,設置cornerRadius、加maskLayer、直接加鏤空圖、內存異步裁剪等等,網絡上一搜一大把,這里就不再重復了。這里有兩點要提醒下,紋理裁剪才是off-screen rendering的原因,而不是設置圓角。當然你要是作死的去設了layer的fillColor,再來設圓角,那就只能說no zuo no die ;另外在使用光柵化時,一定要設置scale以適配屏幕分辨率。

  既然標哥都給出開源方案了,那就比較一下,檢查下自己的不足吧。為參照相同的運行條件,筆者把自己寫的輔助類放到標哥的Demo里,實現相同的效果。然后設計思路、外觀呈現、CPU和內存、幀速、代碼量、侵入性和易用性、適用場景等個方面做出比較。

  標哥的開源庫:https://github.com/CoderJackyHuang/HYBImageCliped

  筆者fork后修改的項目:https://github.com/1962449521/HYBImageCliped

  該功能類的在線維護:https://github.com/1962449521/WHUCornerMaker

  筆者整理中的輔助類集:https://github.com/1962449521/WHUKit/tree/master/WHUKitDemo/WHUKitDemo/WHUKit

 

  以下為筆者方案標哥開源庫的比較

  一、 突破口的選擇

  標哥選擇的起點是內存中剪裁圖片,通過緩存策略優化性能,給UIView、UIImageView、UIButton等控件增加Category以擴展功能。筆者選擇的起點是繪制鏤空圖,同樣使用了緩存以提高復用。因為長期開發SDK盡量不使用Category的習慣,筆者采用輔助類的形式提供功能實現

  二、 功能及解決問題

  主要的出發點都是為了解決圓角圖片離屏渲染影響滑動幀速的問題。標哥采用了剪裁圖片的方式,能夠適應背景非單色情況;在控件內部的圖片,能提供圓角效果,比如按鈕內非抵邊的image;在邊線的繪制上,提供了形狀邊框,邊框有填充和邊線。筆者提供的輔助類只適用背景單色,裁剪針對UIView或其子類整體,邊線只提供單線。

  三、 外觀呈現

   除了雙色邊線外,其它的外觀都能做到相同的效果。

標哥靜態容器 筆者靜態容器
標哥collectionView 筆者collectionView

  

  四、CPU和內存  

  標哥方案CPU使用驟增,最高達到82%。內存使用也高於筆者。因為筆者采用了每次cell出現時重繪邊角,所以CPU略高。如果確定每次cell重用時邊角位置正確,可以不重繪邊角,CPU能穩定在13%左右。圖片相對較少,內存使用差別不明顯。當不同圖片較多時,標哥使用方案需大量緩存裁切好的圖片,猜測會在內存使用上隨之增加。而筆者方案會復用相同角度顏色的邊角,圖片增多時不會增加圓角圖片的內存開銷。

標哥方案
筆者方案

  

  五、 幀速

  滑動幀速基本相近,都有較好的體驗,筆者方案數值相對較高。

標哥方案
筆者方案

    六、代碼量

  標哥使用了一個管理類HYBImageClipedManager,以及提供了UIImage、UIView、UIButton三個類的category,總共約1千行代碼。筆者提供了WHUCornerMaker、WHUBorderMaker兩個輔助功能類,約250行代碼。

    七、侵入性和易用性

  以下為筆者兩個輔助類的頭文件聲明和暴露的使用API,自認為還是較為清晰易用的。這里要說到關於注釋,多余的注釋是違反DRY原則的,不過由於國人對英文的理解不直接或者項目編碼約定,而加了許多不必要的注釋。還是應當以清晰符合語義的方法、變量命名作為首選。至於標哥提供的接入設計,方法太多就不在這里列出了,感興趣的童鞋可以從本文提供的鏈接跳入查看^^

@interface WHUCornerMaker : NSObject

+ (BOOL) isCorneredAtView:(UIView * _Nonnull)view;

// 優先選取view 沿superview上的父類容器的背景色, 如果一直為nil, 則取defaultColor 作為圓角顏色

- (void) roundView:( UIView * _Nonnull ) view withCornerRadius:(CGFloat) radius defaultColor:( UIColor * _Nullable)color;

- (void) roundViews:(NSArray<UIView *> * _Nonnull) views withCornerRadius:(CGFloat) radius  defaultColor:( UIColor * _Nullable)color;

- (void) roundView:(UIView * _Nonnull) view withCornerRadius:(CGFloat) radius defaultColor:( UIColor * _Nullable)color byRoundingCorners:(UIRectCorner)corners;

- (void) roundViews:(NSArray<UIView *> * _Nonnull) views withCornerRadius:(CGFloat) radius  defaultColor:( UIColor * _Nullable)color  byRoundingCorners:(UIRectCorner)corners;


@end
@interface WHUBorderMaker : NSObject

+ (void) borderView:( UIView * _Nonnull ) view withCornerRadius:(CGFloat) radius width:(CGFloat)borderWidth color:(UIColor * _Nonnull)borderColor;


+ (void) borderView:( UIView * _Nonnull ) view withCornerRadius:(CGFloat) radius width:(CGFloat)borderWidth color:(UIColor * _Nonnull)borderColor byRoundingCorners:(UIRectCorner)corners;

@end

 

     八、適用場景

  不可否認,標哥提供了更多功能,比如拿到裁切的圖片,繪制雙色邊框等。不過這樣的使用場景應該是較少的,筆者提供了輔助類能滿足大多數場景的需求。

 

     九、總結

  在做通用性開源庫的時候,可能會考慮更多的東西。但花80%的精力去實現5%使用者的需求是否有必要是有待斟酌的。在筆者方案和標哥方案的比較中,總體而言筆者的方案性能是高出很多,並不隨使用條件復雜性的增加而性能降低。這一方面是內存裁剪圖片本就是騎虎難下的選擇,一方面也是筆者只針對有限的使用場景和需求。

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM