SDAutoLayout的優(yōu)缺點
優(yōu)點
1萤衰、語法簡單(相比官方的語法灵份,Masonry)
2剑刑、純代碼的方式墨吓,代碼維護(hù)容易(相比使用xib,storyboard)
3球匕、UIlabel的內(nèi)容能夠自動根據(jù)內(nèi)容算出寬度
4、UITableviewCell能夠自動算出height
5帖烘、UIView能夠自動算出height
6亮曹、創(chuàng)建的時候,只需要alloc->init秘症,不需要關(guān)心對應(yīng)的frame
缺點
1照卦、 leftspacetoview等方式,經(jīng)常出現(xiàn)UIView布局完以后,不可見乡摹,有時候不太準(zhǔn)役耕,有時候是self的左邊基準(zhǔn),有時候是self的右邊為基準(zhǔn)聪廉,一般來說瞬痘,self的width都是屏幕寬度,所以子控件的x經(jīng)常飛出屏幕
2板熊、 花費(fèi)比預(yù)料多很多的時候去調(diào)試
SDAutoLayout的愛與痛
說真的框全,SDAutoLayout如果真的能夠做到預(yù)計的方便使用,應(yīng)該是很爽的邻邮,但是我個人覺得還是沒有到那步竣况。當(dāng)然也可能是我的能力有限,很多東西都僅僅停留在表面,沒辦法丹泉,不太省心情萤,又開源,又不想輕易放棄摹恨,只能啃源碼了筋岛。
源碼分析
1、項目地址
<pre>https://github.com/gsdios/SDAutoLayout</pre>
2晒哄、文件總數(shù)
說真的睁宰,文件也不太多,就4個寝凌。這也是我愿意啃源碼的一個強(qiáng)有力的原因柒傻。
3、代碼總數(shù)
<pre>
146 ./UITableView+SDAutoTableViewCellHeight.h
374 ./UITableView+SDAutoTableViewCellHeight.m
457 ./UIView+SDAutoLayout.h
1712 ./UIView+SDAutoLayout.m
2689 total
</pre>
4较木、源碼總結(jié)
1)利用關(guān)鍵字sd_layout,生成SDAutoLayoutModel并添加到父類的autoLayoutModelsArray數(shù)組里去红符。
2、在sd_layoutSubviews根據(jù)上面生成的SDAutoLayoutModel計算frame
3)流程分析
一)先使用sd_layout為父類添加一系列的SDAutoLayoutModel類型的數(shù)組autoLayoutModelsArray
二) 在sd_layoutSubviewsHandle根據(jù)autoLayoutModelsArray伐债,遍歷每個子view预侯,計算每個子view的frame
三) 在sd_resizeWithModel函數(shù)里面,生成子view的frame峰锁,如果子frame存在sd_bottomViewsArray和sd_rightViewsArray數(shù)組萎馅,就遞歸執(zhí)行上面的步驟。
5虹蒋、類構(gòu)成
- @interface SDAutoLayoutModel : NSObject
- 包含一系列的關(guān)于frame處理的block
- 還包含一個指向自身的needsAutoResizeView的指針
- @interface UIView (SDAutoHeightWidth)
- 包含主要的面向用戶的API調(diào)用之一,高度糜芳、寬度自適應(yīng)相關(guān)方法,button(高),right(寬)千诬,強(qiáng)制更新UI的約束函數(shù)
- @interface UIView (SDLayoutExtention)
- 設(shè)置圓角半徑耍目、九宮格浮動效果、自動布局回調(diào)block等相關(guān)方法
- @interface UIView (SDAutoLayout)
- 設(shè)置約束徐绑、更新約束、清空約束莫辨、從父view移除并清空約束傲茄、開啟cell的frame緩存等相關(guān)方法
<pre>下面是一個特別的UIView的特別適用方法</pre>
- @interface UIScrollView (SDAutoContentSize)
- UIScrollView 內(nèi)容豎向自適應(yīng)、內(nèi)容橫向自適應(yīng)方法
- UILabel (SDLabelAutoResize)
- 開啟富文本布局沮榜、設(shè)置單行文本label寬度自適應(yīng)盘榨、 設(shè)置label最多可以顯示的行數(shù)
- @interface UIButton (SDExtention)
- UIButton 設(shè)置button根據(jù)單行文字自適應(yīng)
<pre>下面屬于擴(kuò)展熟悉</pre>
@interface SDAutoLayoutModelItem : NSObject
@interface UIView (SDChangeFrame)
最后結(jié)果的處理
@interface SDUIViewCategoryManager : NSObject
5、主要函數(shù)分析
sd_layoutSubviews
1蟆融、利用打樁的里面草巡,在layoutSubviews這個函數(shù),加入sd_sd_layoutSubviewsHandlesd_layoutSubviewsHandle
1型酥、if (self.sd_equalWidthSubviews.count)
//
2山憨、if (self.sd_categoryManager.flowItems.count && (self.sd_categoryManager.lastWidth != self.width_sd))
處理等高處理的view
3查乒、if (self.autoLayoutModelsArray.count)
真正進(jìn)行frame計算的判斷,主要分為兩步郁竟,第一步就是緩存的處理玛迄,第二步(sd_resizeWithModel)是frame的計算。
4棚亩、if (self.tag == kSDModelCellTag && [self isKindOfClass:NSClassFromString(@"UITableViewCellContentView")])
解決UITableviewcell等高計算的蓖议,應(yīng)該是上面的函數(shù)沒有完全解決這個問題,所以需要額外加入這樣的判斷讥蟆。
而且勒虾,是UITableViewCellContentView,而不是UITableViewCell瘸彤,所以在UITableViewCell里面修然,一般應(yīng)該將子UIView放入到self.contentview,而不是view里面,不然這個判斷會失效钧栖,導(dǎo)致cell的高度計算失敗
數(shù)據(jù)計算結(jié)果一般都是使用bottom_sd低零,height_sd等去存儲這些數(shù)據(jù)都是存在于view的。這是新版的處理拯杠,舊版的數(shù)據(jù)沒有后綴_sd掏婶。新版兼容舊版數(shù)據(jù)。主要是@interface UIView (SDChangeFrame)完成
- sd_resizeWithModel
- 功能
- 計算frame的主要函數(shù)
- 流程
- 獲取子view
- 如果不需要自動布局潭陪,退出布局
- // 靠右布局前提設(shè)置
- (layoutWidthWithView:model:)
- widthIs->width->width_sd和fixedWidth
- widthRatioToView->ratio_width->width_sd和fixedWidth
- (layoutHeightWithView:model:)
- heightIs->height->height_sd和fixedHeight
- heightRatioToView->ratio_height->height_sd和fixedHeight
- (layoutLeftWithView:model:)需要重算width_sd
- leftSpaceToView->left->left_sd
- leftEqualToView->equalLeft->left_sd
- centerXEqualToView->equalCenterX->centerX_sd
- centerXIs->centerX->centerX_sd
- (layoutRightWithView:model:)需要重算width_sd
- rightSpaceToView->right->right_sd
- rightEqualToView->equalRight->right_sd
- // 底部布局前提設(shè)置
- (layoutTopWithView:model:)需要重算height_sd
- topSpaceToView->top->top_sd
- topEqualToView->equalTop->top_sd
- centerYEqualToView->equalCenterY->centerY_sd
- centerYIs->centerY->centerY_sd
- autoHeightRatioValue調(diào)用layoutAutoHeightWidthView:model:
- autoHeightRatioValue根據(jù)寬度比例配置高度
- 根據(jù)最大值和最小值進(jìn)行高度重算
- (layoutBottomWithView:model:)需要重算height_sd
- bottomSpaceToView->bottom->bottom_sd
- bottomEqualToView->equalBottom->bottom_sd
- 根據(jù)widthEqualToHeight->widthEqualHeight或者h(yuǎn)eightEqualToWidth->heightEqualWidth去令高寬相等
- 根據(jù)sd_bottomViewsArray和sd_rightViewsArray計算是否遍歷子View的布局雄妥,并且重算高度
- setupCornerRadiusWithView:model,設(shè)置圓角
- sd_cornerRadius->view.layer.cornerRadius
- sd_cornerRadiusFromHeightRatio->view.layer.cornerRadius
- sd_cornerRadiusFromWidthRatio->view.layer.cornerRadius
- 功能