如何设计一个自动布局库

前言:SDAutoLayout 在发布之后受到了众多iOS开发者的青睐和支持,不到半年时间内在GitHub上已经获得2000+star,同时被众多公司和个人开发者作为开发首选自动布局库。现在,以SDAutoLayout为例简单介绍一下如何设计一个自动布局库。

      所谓自动布局,其实就是将手动布局的计算过程抽象出一套算法,然后利用约束模型收集view的宽高左右等各个维度对应的数据,最后在恰当的时机根据约束计算出view的frame。

      了解了这个基本原理之后,我们就可以动手设计一个自动布局库了。在设计自动布局库的过程中,我们主要需要解决以下几个问题:

      1.何时进行自动布局相关运算?

      2.如何实现自动布局算法?

      3.如何设计约束模型管理机制?

     4.如何设计一套简洁的连式语法API?(此步非必须项,仅供有兴趣者参考,以SDAutoLayout为例)

      5.如何实现自动计算cell高度?

1.何时进行自动布局相关运算?

      首先,什么时候进行自动布局相关运算才最合适呢?我们知道,当一个view的frame发生改变或者由于其他情况需要调整子view就会触发layoutSubvies方法,在手动布局时我们经常通过重写这个方法来实现对子view的调整。但是我们要设计自动布局库时,显然不应该强行重写view的layoutSubvies方法,这样就会破坏了开发者对view的自主监听和掌控,因此,layoutSubvies方法执行完毕之后才是我们进行自动布局相关运算的最佳时机。好的,那么究竟如何监控这个“最佳时机”的到来呢?此时我想熟悉OC运行时的同学已经想到了,没错,就是利用OC的黑魔法“Method Swizzling”即可完美解决,代码如下(源码地址 ):

交换layoutSubvies方法

2.如何实现自动布局算法?

      当解决了自动布局运算时机的问题之后,我们面临的下一个问题就是如何设计自动布局算法,这也是整个自动布局库最核心的部分。

      在讲这个布局算法之前,有必要先说一下我总结出的一个自动布局算法要素:先计算绝对属性,后计算相对属性。

      那么,何为“相对属性”?相对属性就是需要参照于其他物体才有意义的属性。比如我们会说“河南在河北的南面”,那么这个“南”就是一个相对属性,有了河北作为参照,这个“南”才是有意义的,如果你只说“河南在南面”,那么这个“南”就是没有意义的。在自动布局中,一个view的x、y、centerX、centerY、left、right等属性就属于这种相对属性。

      对比“相对属性”,“绝对属性”就很好理解了,所谓“绝对属性”就是不依赖于参照物改变而改变的属性。比如我会说“iPhone6 是4.7英寸屏幕”,那么这个“4.7英寸”就是绝对属性,他不会因为和其他参照物比较而改变。在自动布局中,一个view的width、height属性就是这种绝对属性。

      另外,在针对每个“相对属性”计算过程中,“宽高校验”是非常有必要的,如果宽高是不准确的,那么计算出来的right、bottom、centerX、centerY等属性值也肯定是不准确的。示例代码如下(源码地址):

自动布局
right自动布局方法实现

3.如何设计约束模型管理机制?

      然后,我们还要设计一下自动布局约束管理机制,也就是说,每个view的约束该交由谁来管理呢?是view自己?还是view的superView呢?结合刚刚对问题一的分析,既然是父view在调用layoutSubvies方法之后再进行自动布局计算,那么让父view来管理所有子view的约束就再合理不过了。在SDAutoLayout中,每个view都有一个autoLayoutModelsArray数组来管理子view的约束,子view在调用sd_layout方法时候会初始化一个约束模型并添加到其父view的autoLayoutModelsArray数组中,这就是为什么在使用SDAutoLayout过程中要先将子view添加到父view然后再做布局设置的原因了。示例代码如下(源码地址):

初始化约束模型

4.如何设计一套简洁的连式语法API?

      链式语法以其简洁明了的优点受到了众多开发者的推崇,在SDAutoLayout库中,约束模型将各种布局数据设置的操作封装进一个个block中,每次置一个维度的约束时实际上是调用了这个维度对应的block,把相关参数以(参数1,参数2)的形式传递给block进行相关设置,然后block每次把约束模型自身作为返回结果传递下去,这样就可以再次用"."来调用其他维度约束对应的block。示例代码如下(源码地址):

设置约束
每个维度约束对应的block
内部实现

5.如何实现自动计算cell高度?

      SDAutoLayout为开发者提供了简洁高效的cell高度自动计算方法,使用者只需调用一行代码“[yourCell setupAutoHeightWithBottomView:bottomView bottomMargin:bottomMargin];”即可轻松实现cell高度自动计。

      为了实现此功能,SDAutoLayout库在内部建立一个和你的cell一样的模型,然后把你传递过来的model数据赋值给模型cell,设置完成后调用“[self.modelCell.contentView layoutSubviews]”方法来计算cell的真实高度然后返回给你的tableView,同时还会建立cell高度缓存库以供tableView滚动时直接返回cell高度而不必再次计算,如果有需要,你也可以开启cell的Frame缓存机制,这样就会在你的cell出现的时候直接给cell内部控件设置frame而不必时时计算调整,从而大大增加了滚动流畅度。示例代码如下(源码地址):

开启cell的frame缓存
返回cell高度
返回并缓存cell高度

      好了,今天先简单介绍到这里,后期还会针对以上提到的五点内容进行详细深入的介绍,如有好的意见和建议欢迎到SDAutoLayout的GitHub地址https://github.com/gsdios/SDAutoLayout issue我,Thanks!



SDAutoLayout的GitHub地址:https://github.com/gsdios/SDAutoLayout

SDAutoLayout使用者开发的部分app截图http://www.jianshu.com/p/9bc04d3effb8

自动布局QQ交流群:497140713(1群)  519489682(已满)

自动布局视频教程:

SDAutoLayout 基础版视频教程:http://www.letv.com/ptv/vplay/24038772.html

SDAutoLayout 进阶版视频教程:http://www.letv.com/ptv/vplay/24381390.html

SDAutoLayout 原理简介视频教程:http://www.iqiyi.com/w_19rt0tec4p.html

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

推荐阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,016评论 4 62
  • 2017.02.22 可以练习,每当这个时候,脑袋就犯困,我这脑袋真是神奇呀,一说让你做事情,你就犯困,你可不要太...
    Carden阅读 1,321评论 0 1
  • Creating Custom Layouts 为穿戴式设备创建布局和在手机上的操作一样,不过为了整体平衡和谐感你...
    lucky9322阅读 481评论 0 3
  • 电面要点 安静地坐下来,拿着纸笔进行记录。 用重视、严谨的态度来对待电话面试。 接听电话时要用“你好”等礼貌用语。...
    Hello_Lisa阅读 205评论 0 0
  • 关注简书很久了,自己也一直很想提笔写一些东西,但是由于自己的惰性一直没能行动。今天想来想去,还是想要动笔写一些,作...
    行脚人阅读 273评论 0 1