iOS SDAutoLayout(自动布局)~详解

//联系人:石虎QQ: 1224614774昵称:嗡嘛呢叭咪哄

一、概念

SDAutoLayout如果真的能够做到预计的方便使用,应该是很爽的,但是我个人觉得还是没有到那步。当然也可能是我的能力有限,很多东西都仅仅停留在表面,没办法,不太省心,又开源,又不想轻易放弃,只能啃源码了。

优点

1、语法简单(相比官方的语法,Masonry)

2、纯代码的方式,代码维护容易(相比使用xib,storyboard)

3、UIlabel的内容能够自动根据内容算出宽度

4、UITableviewCell能够自动算出height

5、UIView能够自动算出height

6、创建的时候,只需要alloc->init,不需要关心对应的frame

缺点

1、 leftspacetoview等方式,经常出现UIView布局完以后,不可见,有时候不太准,有时候是self的左边基准,有时候是self的右边为基准,一般来说,self的width都是屏幕宽度,所以子控件的x经常飞出屏幕

2、 花费比预料多很多的时候去调试

二、源码分析

1、项目地址

https://github.com/gsdios/SDAutoLayout

2、文件总数

说真的,文件也不太多,就4个。这也是我愿意啃源码的一个强有力的原因。

3、代码总数

146 ./UITableView+SDAutoTableViewCellHeight.h

374 ./UITableView+SDAutoTableViewCellHeight.m

457 ./UIView+SDAutoLayout.h

1712 ./UIView+SDAutoLayout.m

2689 total

4、源码总结

1)利用关键字sd_layout,生成SDAutoLayoutModel并添加到父类的autoLayoutModelsArray数组里去。

2、在sd_layoutSubviews根据上面生成的SDAutoLayoutModel计算frame

3)流程分析

一)先使用sd_layout为父类添加一系列的SDAutoLayoutModel类型的数组autoLayoutModelsArray

二) 在sd_layoutSubviewsHandle根据autoLayoutModelsArray,遍历每个子view,计算每个子view的frame

三) 在sd_resizeWithModel函数里面,生成子view的frame,如果子frame存在sd_bottomViewsArray和sd_rightViewsArray数组,就递归执行上面的步骤。

5、类构成

@interface SDAutoLayoutModel : NSObject

包含一系列的关于frame处理的block

还包含一个指向自身的needsAutoResizeView的指针

@interface UIView (SDAutoHeightWidth)

包含主要的面向用户的API调用之一,高度、宽度自适应相关方法,button(高),right(宽),强制更新UI的约束函数

@interface UIView (SDLayoutExtention)

设置圆角半径、九宫格浮动效果、自动布局回调block等相关方法

@interface UIView (SDAutoLayout)

设置约束、更新约束、清空约束、从父view移除并清空约束、开启cell的frame缓存等相关方法

下面是一个特别的UIView的特别适用方法

@interface UIScrollView (SDAutoContentSize)

UIScrollView 内容竖向自适应、内容横向自适应方法

UILabel (SDLabelAutoResize)

开启富文本布局、设置单行文本label宽度自适应、 设置label最多可以显示的行数

@interface UIButton (SDExtention)

UIButton 设置button根据单行文字自适应

下面属于扩展熟悉

@interface SDAutoLayoutModelItem : NSObject

@interface UIView (SDChangeFrame)

最后结果的处理

@interface SDUIViewCategoryManager : NSObject

5、主要函数分析

sd_layoutSubviews

1、利用打桩的里面,在layoutSubviews这个函数,加入sd_sd_layoutSubviewsHandle

sd_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)

真正进行frame计算的判断,主要分为两步,第一步就是缓存的处理,第二步(sd_resizeWithModel)是frame的计算。

4、if (self.tag == kSDModelCellTag && [self isKindOfClass:NSClassFromString(@"UITableViewCellContentView")])

解决UITableviewcell等高计算的,应该是上面的函数没有完全解决这个问题,所以需要额外加入这样的判断。

而且,是UITableViewCellContentView,而不是UITableViewCell,所以在UITableViewCell里面,一般应该将子UIView放入到self.contentview,而不是view里面,不然这个判断会失效,导致cell的高度计算失败

数据计算结果一般都是使用bottom_sd,height_sd等去存储这些数据都是存在于view的。这是新版的处理,旧版的数据没有后缀_sd。新版兼容旧版数据。主要是@interface UIView (SDChangeFrame)完成

sd_resizeWithModel

功能

计算frame的主要函数

流程

获取子view

如果不需要自动布局,退出布局

// 靠右布局前提设置

(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

// 底部布局前提设置

(layoutTopWithView:model:)需要重算height_sd

topSpaceToView->top->top_sd

topEqualToView->equalTop->top_sd

centerYEqualToView->equalCenterY->centerY_sd

centerYIs->centerY->centerY_sd

autoHeightRatioValue调用layoutAutoHeightWidthView:model:

autoHeightRatioValue根据宽度比例配置高度

根据最大值和最小值进行高度重算

(layoutBottomWithView:model:)需要重算height_sd

bottomSpaceToView->bottom->bottom_sd

bottomEqualToView->equalBottom->bottom_sd

根据widthEqualToHeight->widthEqualHeight或者heightEqualToWidth->heightEqualWidth去令高宽相等

根据sd_bottomViewsArray和sd_rightViewsArray计算是否遍历子View的布局,并且重算高度

setupCornerRadiusWithView:model,设置圆角

sd_cornerRadius->view.layer.cornerRadius

sd_cornerRadiusFromHeightRatio->view.layer.cornerRadius

sd_cornerRadiusFromWidthRatio->view.layer.cornerRadius

谢谢!!!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,524评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,869评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,813评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,210评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,085评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,117评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,533评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,219评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,487评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,582评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,362评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,218评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,589评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,899评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,176评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,503评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,707评论 2 335

推荐阅读更多精彩内容

  • SDAutoLayout的优缺点 优点 1、语法简单(相比官方的语法,Masonry)2、纯代码的方式,代码维护容...
    翻这个墙阅读 1,303评论 0 1
  • ~ 写在正文之前:文章转移到翻这个墙中,希望继续关注啦。(2017.11.5) SDAutoLayout的优缺点 ...
    翻个墙阅读 9,571评论 3 7
  • iOS_autoLayout_Masonry 概述 Masonry是一个轻量级的布局框架与更好的包装AutoLay...
    指尖的跳动阅读 1,142评论 1 4
  • iOS中UI的布局是很重要的,而在前期开发中就要选定好布局的方法,因为这对整个工程乃至于后期的版本维护都有很重要...
    進无尽阅读 1,489评论 1 8
  • 转自:http://www.code4app.com/blog-866962-1317.html1、设置UILab...
    MMOTE阅读 1,570评论 1 1