1.為什么autolayout?
? ? ?盡管autolayout推出的時間已經(jīng)不短了(自ios6以后就可以使用),但是在很長的時間段里,有很多人都不太了它,包括我自己,因為以前手寫frame的時代我們已經(jīng)太過習慣,而且以前也有不少吐槽autolayout的文章,包括性能,API等等一些方面,加上以前的iPhone的屏幕只有3.5~4inch兩種,所以很多人都忽略了這項技術(shù)。不過有了iPhone6及plus以后,這樣的問題就凸顯了,手寫frame的習慣讓我痛苦不堪,想想自己寫了一大堆和業(yè)務邏輯無關(guān)的布局代碼就頭疼,于是我也開始意識到autolayout是不得不用的了。
2.autolayout的方式
?1.手寫代碼添加constraints(如下圖)

向上面這樣的寫法不過是把一個視圖的centerX ,centerY于父視圖響應的centerX,centerY對齊(忽略這緞帶代碼中的constant參數(shù),暫時把它們都當作0吧),卻也要寫一大段,看著也很費勁,不過官方的API這樣設計當然是有道理的,我們要完全的控制布局,就得要這么多的參數(shù),不過這樣的方式顯然我不會喜歡。
2.Xib文件拖拽添加約束
?既然有手寫代碼添加constraints,當然會有Xib添加constraints的方式了。這種方式相對于手寫代碼帶來的是,少了很多讓人煩的代碼,直接操作視圖拖拽的便捷性,當然也有很多的缺點,比如這種方式很容易出現(xiàn)警告,錯誤,不容易更改等,都是因為相對于手寫代碼要注意的地方更多。比如我在項目中添加的constraints:(如下圖)

看到這樣的xib你是不是快瘋了,如果把這樣xib要重新布局設計,換一個人來做,那個人肯定是痛苦死了。
說到這里,好像是一直在吐槽autolayout的缺點一樣。難道就沒有簡單的方式嗎?當然有,在你意識到這些缺點的時候,相信有很多人都會試著去改善這些,比如masonry這個第三方庫,就很好的為我們提供了一種簡便的手寫代碼添加constraints的方式:(如下圖)

是不是很方便也很容易理解,這就是了,我也在項目的很多地方用到了它,為我省去了很多的時間。
3.tableView,collectionView中的autoLayout
? ? ?說到這里才是真正的到了正題,在app的開發(fā)中,列表視圖時最常用的一個UI控件,當我們使用tableView或者是collectionView的時候,免不了的要對cell進行計算height,size,這時候正是autolayout大顯身手的地方了。這里說一下tableView使用autolayout的一些細節(jié),collectionView同理。
? ? ? 比如要實現(xiàn)這樣的一個列表:

cell中有兩個動態(tài)變化的因素,1 是文本的長度不固定,2 是圖片的尺寸不固定,這樣就導致了cell的高度是動態(tài)變化的,從服務器獲取到數(shù)據(jù)以后展示,cell要根據(jù)數(shù)據(jù)動態(tài)的布局,如果有圖片則根據(jù)圖片尺寸展示圖片和文本,如果沒有圖片則只展示文本,文本的最大行數(shù)為4行。這里我用的一種cell來做,或許你會說為什么不分兩種類型的cell來做,我要說的是兩種又怎么樣,cell圖片的尺寸又不是固定的,分兩種還是要動態(tài)的計算高度?。。?!如果是same這樣的那就簡單一些了
雖然每個cell的高度也是動態(tài)的,但是cell中動態(tài)變化的摯友文本,而圖片的尺寸卻是固定的,不論你的圖片的長寬比時怎么樣的,看圖 6的這種布局,圖片上下都有一坨空白,是不是有點傻?好了,有了比較以后就繼續(xù)吧。
一下時我的cell.m中的代碼片段

首先我在awakeFromNib中對cell的contentView子視圖做了一些配置,這里需要注意的是self.contentView.translatesAutoresizingMaskIntoConstraints=NO;把xcode為你自動添加的autoresizingMask標記為失效,這樣cell就會真正完全的按照你自己的布局來工作,self.contentLabel.preferredMaxLayoutWidth=kScreenWidth-74;這個就是設置文本那個label的最大展示寬度,autolayout會根據(jù)這個值來布局。

然后使用數(shù)據(jù)填充cell的時候,看是否有圖片,有圖片就設置imageSize為響應的size,沒有則設置圖片為CGSizeZero,調(diào)用[self setNeedsUpdateConstraints];
[self updateConstraintsIfNeeded]; 告訴cell要更新constraints了,然后在cell的系統(tǒng)方法里面更新constraints:

這樣cell的布局就完了。接下來看tableView的dataSource都寫了些什么:

簡單吧,沒有計算高度的協(xié)議方法,只需要把數(shù)據(jù)丟給cell,當然前提是你的deployment target >= 8.0,并且需要設置self.tableView.estimatedRowHeight=100(大于0);就好了。
如果你要支持8.0以下的話加上下面這個方法吧。

就此不對這個方法里的布局方法做詳細描述。