iOS AutoLayout還能夠這樣玩

Auto Layout


網上關於Auto Layout的文章繁多, 可是總以爲有些內容並無說清楚。因此在這篇博文,我將經過一個demo演示Auto Layout中幾個容易被忽略,可是又至關重要的概念html


demo效果

demo效果

demo 中要經過約束要實現的效果以下:bash

  1. backgroundView width>=60;
  2. backgroundView的width隨着Label中內容的增長而增長
  3. backgroundView與其superView的margin>=30。也就是當Label的內容過長時,會顯示出省略號。

概念

要實現demo 中的效果前,須要知道下面的幾個概念:app

1, Constraint equalities(暫且叫作約束等式):這個就是常見的約束類型。再也不贅述,舉幾個例子:佈局

Red.top = 1.0 * Superview.top + 20.0
Superview.bottom = 1.0 * Red.bottom + 20.0
Red.top = 1.0 * Blue.top + 0.0
Red.bottom = 1.0 * Blue.bottom + 0.0
複製代碼

2, Constraint Inequalities(暫且叫作約束不等式):它指定一個區域而不是一個確切的值。ui

// Setting the minimum width
View.width >= 0.0 * NotAnAttribute + 40.0
 
// Setting the maximum width
View.width <= 0.0 * NotAnAttribute + 280.0
複製代碼

3,Constraint Priorities約束優先級 : 約束優級是一個0-1000的數值。當兩個約束出現衝突時,優先級高的約束將保留,優先級低的約束失效。spa

4,Intrinsic Content Size內在內容size: 有些view 能夠根據其內容設定其size。好比說UILabel,UIButton等,他們的size恰好可以容納其內容支持Intrinsic Content Size的view以下: 3d

Intrinsic Content Size

5, content-hugging priorities 抗拉伸優先級(默認250) :這個優先級與 Intrinsic Content Size相關。假如一個Label的Intrinsic Content Size width=50, 如今添加一個width=60的約束(默認優先級是1000)如今Label就會拉伸 。若是將 約束width=60的優先級設置成小於250的值,Label就不會被拉伸。
6, compression-resistance priorities 抗壓縮優先級(默認750):這個優先級也與 Intrinsic Content Size相關。假如一個Label的Intrinsic Content Size width=50, 如今添加一個width=40的約束(默認優先級是1000)如今Label就會壓縮 。若是將 約束width=40的優先級設置成小於750的值,Label就不會被壓縮。 能夠看出 content-hugging prioritiescompression-resistance priorities用於抵抗其餘約束對viewIntrinsic Content Size的改變。code

###實戰 介紹完上面的概念,讓咱們使用他們完成上面demo效果。cdn

1, 新建工程,打開storyboard。添加backgroundView(繼承自UIView), 設置背景顏色爲灰色並添加 水平居中和垂直居中約束。此時會出現約束錯誤,這是由於這個backgroundView只設置了position,沒有設置size。 沒必要擔憂,一會就可解決這個問題;htm

約束以下:

pic1

pic2
2, 在backgroundView中添加一個 ActivityIndicatorView 和 Label。(下面還添加了一個button, 當點擊下面的button時,label中的內容會增長)

view層級關係以下:

pic3

添加下列約束:

pic4
pic5

此時的約束沒有任何錯誤了顯示效果以下:

pic6

3, 此時經過給Label添加文字,backgroundView也會相應增大(只分析水平方向)。爲何增大? 這是由於Label的text決定Intrinsic Content Size的大小, text增多,Intrinsic Content Size相應增長。Label與backgroundView 的margin爲10。因此根據這一系列的關係致使了 給Label添加文字,backgroundView也會相應增大。

pic7

4, 如今有個問題, 當label中的文字太多時,backgroundView的寬度會超出其父view範圍,這顯然不太好。添加一個約束使backgroundView與其父view之間有一個最小的margin。 這時就要使用約束不等式了。約束不等式能夠指定一個範圍而不是一個確切的數值。看下面的例子。

pic8

添加以下約束, 這樣backgroundView和superView 之間的margin最小是30。當label中的內容過長時,內容就會被壓縮。But Why?

pic9
pic10

5 , backgroundView 的width隨Label中內容的增長而增長。 當backgroundView 與其superView 的margin=30後,再增長 backgroundView 的width就會產生約束衝突了(與以前設置的 ‘backgroundView和superView 之間的margin最小是30’ 這條約束產生衝突 )。那麼stroyboard是如何解決衝突的那? 對,就是優先級。 ‘backgroundView和superView 之間的margin最小是30’這條約束的優先級時1000, 是最大優先級。 Label 的抗壓縮優先級默認750,1000>750, Label這能被壓縮了(內容省略了一部分)。若是你將這兩個優先級大小交換一下,backgroundView與superView 就之間不會出現margin了。

6, 當label中有一個字母是, 效果是這樣的。 好醜。。。。

pic11

咱們給backgroundView設置一個最小width約束。 咱們設置backgroundView的width =60約束, 並設置優先級996。(固然,你也能夠使用width >=60這樣的約束。這裏爲了演示優先級) 如今的效果是這個樣子的:

pic12

又出問題了。。。 雖然backgroundView width=60確實起做用了,可是Label內容增長時backgroundView的width並無增長。這仍是優先級的問題。Label 的抗壓縮優先級是750, backgroundView width=60的優先級時996,996>750, 固然會出問題了。 如今只需讓 Label的抗壓縮優先級大於backgroundView width=60的優先級就能夠了 。

7, 關於抗拉伸優先級,沒想到很好的例子,就不演示了。

結語

一種佈局效果能經過多種約束方式實現出來,關鍵是思路清晰,一步一步的來。 參考資料,固然是 官網了。但願對你有幫助,若有幫助就給個喜歡吧。

相關文章
相關標籤/搜索