本文主要介紹幾個我遇到並總結的相對高級的用法(固然啦牛人會以爲這也不算什麼)。 簡單的storyboard中上下左右約束,固定寬高啥的用法在這裏就不作贅述了。javascript
autolayout自動佈局是iOS6之後出現的,可是在開始的一段時間裏你們並不怎麼會用,都是一上來先勾掉。以後隨着5s,iPhone6的出現屏幕多種多樣。用多層if來判斷尺寸已經徹底hold不住了纔開始學習自動佈局。html
在這以前有個叫自動伸縮的autoresizing屬性,這個主要用於一個控件和本身父控件之間的關係。只有autolayout才真正能夠在任意兩個控件中創建關係。java
若是你不是在董鉑然博客園看到本文 請點擊查看原文git
autoresizing須要注意的是 storyboard中設置的約束和手碼中設置的約束是相反的。 storyboard圖形頁面裏點的右邊的線和下邊的線的意思是「固定」github
而手碼中經常使用的autoresizingMasks屬性中的枚舉都是Flexible可「伸縮」的。 因此假如想要讓右邊和下邊的距離固定,在代碼中應該設置左邊和上邊的可伸縮約束。框架
yellowView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin |UIViewAutoresizingFlexibleTopMargin;
有了autolayout以後這個自動伸縮不多用了 一共七個屬性。less
無,寬可伸縮,高可伸縮,左間距可伸縮,右間距可伸縮,上間距可伸縮,下間距可伸縮佈局
UIViewAutoresizingNone = 0,學習
UIViewAutoresizingFlexibleWidth = 1 << 1,動畫
UIViewAutoresizingFlexibleHeight = 1 << 4,
UIViewAutoresizingFlexibleLeftMargin = 1 << 0,
UIViewAutoresizingFlexibleRightMargin = 1 << 2,
UIViewAutoresizingFlexibleTopMargin = 1 << 3,
UIViewAutoresizingFlexibleBottomMargin = 1 << 5
每一個枚舉值都是位移枚舉,能夠在一行代碼中傳多個值。
label想要在界面中顯示成這樣
意義是下面的控件能夠根據上面label的底部進行自動調整。
這個不是用sizetofit設置的,而是用約束,會在程序運行中數據變了約束當即改變,尺寸也當即改變。
這種設計方法是:
1.設置label的左邊和上邊的約束,而後再設置下最寬度約束假設是150,把label裏面的lines屬性設置成0即隨意任意多行。 這樣裏面的文字就會自動換行而且一直顯示完,label的背景色也是自動匹配。
2.可是右邊還多出了一塊。label的右邊還有一塊藍色並非牢牢的挨着。這時就要選中那個寬度的約束 再到右邊把Relation由本來的equal改爲 less than or Equal 。這時候左邊的約束顯示變了 變成≤了。
運行以後結果是:這裏能夠清楚的看到label的右邊牢牢挨着邊了。
3.可是有時候數據可能爲空,一旦爲空label的大小就被擠沒有了,下面的控件也凌亂了。因此爲了保證就算數據沒有空當也要留着佔位,就找給他設置兩個高度約束,一個是大於等於一個是小於等於,包裹成一個範圍。 這時候要把上面width的小於等於改爲equal。
就像這樣 這時候運行效果 遇到大量文字和沒文字的兩種效果是
起到了佔位的做用。即便文字沒有地方還在。
左邊的圖constraints有的在label節點下有的在View節點下,到底是什麼緣由決定了constraints在哪一個節點下面?
是看這個約束是否依賴了別的控件,若是就是本身設置固定寬高啥的不關係到別人那就是在本身下面。若是依賴誰設置了間距,那這個約束就會放在本身和依賴的控件的最小公共父控件下。
如圖
storyboard界面裏面的托拉拽當然方便可是不能批量操做(董鉑然原創),假若有相似的30個小控件,storyboard就太麻煩了,手碼的話一個循環就完事了
手碼建立就是所謂的那七個參數的長的像句子似得方法
以後再在相應的節點下添加約束,有添加一個和添加一組 兩種方法。
// 高度約束(添加到yellowView身上) NSLayoutConstraint *heightConstraint = [NSLayoutConstraint constraintWithItem:yellowView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:0.0 constant:50]; [yellowView addConstraint:heightConstraint]; // 間距約束(添加到self.view身上) CGFloat margin = 20; [self.view addConstraints:@[ // 左邊 [NSLayoutConstraint constraintWithItem:yellowView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeft multiplier:1.0 constant:margin], // 右邊 [NSLayoutConstraint constraintWithItem:yellowView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeRight multiplier:1.0 constant: - margin], // 底部 [NSLayoutConstraint constraintWithItem:yellowView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1.0 constant: - margin] ]]; }
這裏用到了一個核心公式,任何兩個控件間的約束均可以經過這個公式算出
obj1.property1 =(obj2.property2 * multiplier)+ constant value
multiplier和constant 就是向量係數和偏移量
還有爲了不和系統生成的自動伸縮的約束不衝突 通常加上這句
系統默認這個屬性是yes
NSArray *contraints = [NSLayoutConstraint constraintsWithVisualFormat:vfl options:kNilOptions metrics:metrics views:views];
VFL的詳細語法 能夠在官方文檔中 搜 「Visual Format」 就能搜到
上面的方法中傳到的兩個參數metrics 和 views 是兩個字典。(董鉑然原創) 第一個字典metrics是用來告訴系統裏面的每個值對應哪一個字母
第二個字典views是 用來告訴裏面的每個控件對應字符串裏的什麼
若是整個VFL語言裏的全部控件你都是用原名寫在裏面的,那能夠用宏代替
括號裏能夠傳多個值逗號隔開
有 Masonry 和 UIView+Autolayout
框架地址是:
https://github.com/Masonry/Masonry
https://github.com/smileyborg/UIView-AutoLayout
這個相對於masonry,是個輕量級的框架易於上手,裏面一共也就兩個文件。也很是好用,都是用auto開頭。適用於約束不常常改變的項目
事例用法:
直接設置四周的間隔距離
[self.yellowView autoPinEdgesToSuperviewEdgesWithInsets:UIEdgeInsetsMake(20, 20, 20, 20)]; //直接設置四周的間隔距離
設置三個間隔,而後再添加個高度,
[self.yellowView autoPinEdgesToSuperviewEdgesWithInsets:UIEdgeInsetsMake(20, 20, 20, 20)excludingEdge:ALEdgeTop]; // 讓頂部約束無效 [self.yellowView autoSetDimension:ALDimensionHeight toSize:100]; // 本身再添加個高度約束正好四個
也能夠直接設置大小
[self.yellowView autoSetDimensionsToSize:CGSizeMake(200, 200)];
總之還有不少用法,在這不一一介紹了,大概就是這個代碼風格。有興趣的能夠去上面說的那個github地址上仔細查看。
[yellowView mas_makeConstraints:^(MASConstraintMaker *make) { // make表明yellowView // 添加約束 make.edges.equalTo(self.view).insets(UIEdgeInsetsMake(20, 20, 20, 20)); }];
下面這個是更新約束,很是方便會自動識別上左下右的屬性來更改。
[self.yellowView mas_updateConstraints:^(MASConstraintMaker *make) { make.left.equalTo(self.view.mas_left).offset(100); make.top.equalTo(self.view.mas_top).offset(100); make.right.equalTo(self.view.mas_right).offset(-100); make.bottom.equalTo(self.view.mas_bottom).offset(-100); }];
還有一些別的屬性用法。
主要是做者設置的屬性比較多這張圖摘自他的github,有興趣能夠去github仔細看