幾乎在我們所有的iOS App 項(xiàng)目中我們都為了開(kāi)發(fā)方便戳玫,為了Deadline都會(huì)在我們的項(xiàng)目中使用一些別人造好的輪子。使用這些輪子一般都很簡(jiǎn)單,但是我們也要好好學(xué)習(xí)別人造的這些輪子背后的原因,大神們?yōu)槭裁匆@么造?閱讀大神們的代碼來(lái)理解他們的造這些輪子的思想與方法對(duì)我們能力的提示也會(huì)有很大幫助家制。這篇文章就簡(jiǎn)單寫(xiě)一下我閱讀SDAutoLayout這個(gè)自動(dòng)布局開(kāi)源庫(kù)的源碼之后的理解吧。
直接上代碼:
UILabel *titleLabel = [[UILabel alloc]init];
titleLabel.text = @"test string";
[self.view addSubview:titleLabel];
titleLabel.sd_layout
.leftSpaceToView(self.view,20)
.topSpaceToView(self.view,100)
.rightSpaceToView(self.view,20)
.heightIs(20);
上面這段代碼就是就是用SDAutoLayout對(duì)一個(gè)Label進(jìn)行適配不同屏幕的簡(jiǎn)單例子泡一。很簡(jiǎn)單颤殴、很暴力,并且是我們用起來(lái)很方便的鏈?zhǔn)秸{(diào)用方式鼻忠。我們進(jìn)行斷點(diǎn)調(diào)試進(jìn)入到SDAutoLayout的源代碼中涵但。
首先執(zhí)行sd_layout這個(gè)方法,這個(gè)方法的作用就是創(chuàng)建并初始化一些參數(shù)返回SDAutoLayoutModel這個(gè)對(duì)象的實(shí)例帖蔓,然后就真正的開(kāi)始進(jìn)行自動(dòng)布局的代碼矮瘟。
接下來(lái)查看leftSpaceToView()這個(gè)方法會(huì)看到這個(gè)方法是一個(gè)懶加載的方法,在懶加載的方法中會(huì)執(zhí)行這個(gè)方法marginToViewblockWithKey塑娇,這個(gè)方法很有意思澈侠,其中的key與SDAutoLayoutModel的私有屬性left相同。
進(jìn)入到這個(gè)方法就可以看到返回值為一個(gè)block埋酬,而且在block中會(huì)通過(guò)KVC的方式設(shè)置SDAutoLayoutModel實(shí)例的屬性(與這個(gè)方法的key名字相同)的value為SDAutoLayoutModelItem的實(shí)例對(duì)象哨啃,仔細(xì)發(fā)現(xiàn)SDAutoLayoutModel實(shí)例的私有屬性的類型就是SDAutoLayoutModelItem。咋下面中我們也可到作者提供了這些屬性的set方法写妥,我們剛學(xué)KVC的時(shí)候大家都知道拳球,KVC的機(jī)制是首先從調(diào)用setter方法,找不到setter方法就查找對(duì)象是否存在屬性等的直到找不到任何相關(guān)的就會(huì)報(bào)錯(cuò)耳标。我們查看這些setter方法就可以看到這寫(xiě)setter方法就是設(shè)置當(dāng)前view的frame的屬性醇坝。
到這個(gè)時(shí)候我們就明白了這個(gè)第三方庫(kù)的核心還是設(shè)置view的frame來(lái)進(jìn)行適配邑跪。但是還有一點(diǎn)不同次坡,在這個(gè)方法中還使用了黑魔法(runtime)Method Swizzing,在load方法中替換了layoutSubViews画畅。因?yàn)樵趇OS中設(shè)置view的frame就會(huì)自動(dòng)調(diào)用layoutSubViews這個(gè)方法砸琅,下面是會(huì)調(diào)用layoutSubViews方法的情況:
1. 直接調(diào)用setLayoutSubviews。(這個(gè)在上面蘋(píng)果官方文檔里有說(shuō)明)
2. addSubview的時(shí)候轴踱。
3. 當(dāng)view的frame發(fā)生改變的時(shí)候症脂。
4. 滑動(dòng)UIScrollView的時(shí)候。
5. 旋轉(zhuǎn)Screen會(huì)觸發(fā)父UIView上的layoutSubviews事件。
6. 改變一個(gè)UIView大小的時(shí)候也會(huì)觸發(fā)父UIView上的layoutSubviews事件诱篷。
在替換的sd_layoutSubviews中執(zhí)行了sd_layoutSubviewsHandle這個(gè)方法壶唤,這個(gè)方法就是針對(duì)不同的view及情況進(jìn)行寬度、高度等屬性進(jìn)行計(jì)算棕所,并且會(huì)緩存tableViewCell的高度等闸盔。
接下來(lái)的topSpaceToView、rightSpaceToView琳省、heightIs等方法跟leftSpaceToView方法類似迎吵,大同小異,我就不做一一解釋了针贬。
總結(jié)一下這個(gè)開(kāi)源庫(kù)的原理就是通過(guò)KVC击费、鏈?zhǔn)秸{(diào)用、Runtime的Method Swizzing等技術(shù)創(chuàng)造的輪子桦他。這個(gè)庫(kù)還提供了一些其他功能蔫巩,我們平時(shí)開(kāi)發(fā)使用起來(lái)還是很簡(jiǎn)單方便的,能很大程度上提高我們的開(kāi)發(fā)效率快压。工作之余可以多學(xué)學(xué)作者怎么使用這些技術(shù)創(chuàng)造輪子以及為什么這樣寫(xiě)也是一件很有趣的事情批幌。