SDAutoLayout的優(yōu)缺點(diǎn)
優(yōu)點(diǎn)
1、語法簡單(相比官方的語法,Masonry)
2、純代碼的方式,代碼維護(hù)容易(相比使用xib,storyboard)
3、UIlabel的內(nèi)容能夠自動(dòng)根據(jù)內(nèi)容算出寬度
4、UITableviewCell能夠自動(dòng)算出height
5、UIView能夠自動(dòng)算出height
6、創(chuàng)建的時(shí)候,只需要alloc->init,不需要關(guān)心對(duì)應(yīng)的frame
缺點(diǎn)
1、 leftspacetoview等方式,經(jīng)常出現(xiàn)UIView布局完以后,不可見,有時(shí)候不太準(zhǔn),有時(shí)候是self的左邊基準(zhǔn),有時(shí)候是self的右邊為基準(zhǔn),一般來說,self的width都是屏幕寬度,所以子控件的x經(jīng)常飛出屏幕
2、 花費(fèi)比預(yù)料多很多的時(shí)候去調(diào)試
SDAutoLayout的愛與痛
說真的,SDAutoLayout如果真的能夠做到預(yù)計(jì)的方便使用,應(yīng)該是很爽的,但是我個(gè)人覺得還是沒有到那步。當(dāng)然也可能是我的能力有限,很多東西都僅僅停留在表面,沒辦法,不太省心,又開源,又不想輕易放棄,只能啃源碼了。
源碼分析
1、項(xiàng)目地址
<pre>https://github.com/gsdios/SDAutoLayout</pre>
2、文件總數(shù)
說真的,文件也不太多,就4個(gè)。這也是我愿意啃源碼的一個(gè)強(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計(jì)算frame
3)流程分析
一)先使用sd_layout為父類添加一系列的SDAutoLayoutModel類型的數(shù)組autoLayoutModelsArray
二) 在sd_layoutSubviewsHandle根據(jù)autoLayoutModelsArray,遍歷每個(gè)子view,計(jì)算每個(gè)子view的frame
三) 在sd_resizeWithModel函數(shù)里面,生成子view的frame,如果子frame存在sd_bottomViewsArray和sd_rightViewsArray數(shù)組,就遞歸執(zhí)行上面的步驟。
5、類構(gòu)成
- @interface SDAutoLayoutModel : NSObject
- 包含一系列的關(guān)于frame處理的block
- 還包含一個(gè)指向自身的needsAutoResizeView的指針
- @interface UIView (SDAutoHeightWidth)
- 包含主要的面向用戶的API調(diào)用之一,高度、寬度自適應(yīng)相關(guān)方法,button(高),right(寬),強(qiáng)制更新UI的約束函數(shù)
- @interface UIView (SDLayoutExtention)
- 設(shè)置圓角半徑、九宮格浮動(dòng)效果、自動(dòng)布局回調(diào)block等相關(guān)方法
- @interface UIView (SDAutoLayout)
- 設(shè)置約束、更新約束、清空約束、從父view移除并清空約束、開啟cell的frame緩存等相關(guān)方法
<pre>下面是一個(gè)特別的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這個(gè)函數(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計(jì)算的判斷,主要分為兩步,第一步就是緩存的處理,第二步(sd_resizeWithModel)是frame的計(jì)算。
4、if (self.tag == kSDModelCellTag && [self isKindOfClass:NSClassFromString(@"UITableViewCellContentView")])
解決UITableviewcell等高計(jì)算的,應(yīng)該是上面的函數(shù)沒有完全解決這個(gè)問題,所以需要額外加入這樣的判斷。
而且,是UITableViewCellContentView,而不是UITableViewCell,所以在UITableViewCell里面,一般應(yīng)該將子UIView放入到self.contentview,而不是view里面,不然這個(gè)判斷會(huì)失效,導(dǎo)致cell的高度計(jì)算失敗
數(shù)據(jù)計(jì)算結(jié)果一般都是使用bottom_sd,height_sd等去存儲(chǔ)這些數(shù)據(jù)都是存在于view的。這是新版的處理,舊版的數(shù)據(jù)沒有后綴_sd。新版兼容舊版數(shù)據(jù)。主要是@interface UIView (SDChangeFrame)完成
- sd_resizeWithModel
- 功能
- 計(jì)算frame的主要函數(shù)
- 流程
- 獲取子view
- 如果不需要自動(dòng)布局,退出布局
- // 靠右布局前提設(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計(jì)算是否遍歷子View的布局,并且重算高度
- setupCornerRadiusWithView:model,設(shè)置圓角
- sd_cornerRadius->view.layer.cornerRadius
- sd_cornerRadiusFromHeightRatio->view.layer.cornerRadius
- sd_cornerRadiusFromWidthRatio->view.layer.cornerRadius
- 功能