1吸耿、autolayout的計算公式:
firstItem.firstAttribute(R)SecondItem.secondAttribute*m+b;R:relations:Multiplierb:Constant
2、優(yōu)先級
Hugging priority 確定view有多大的優(yōu)先級阻止自己變大酷窥。
Compression Resistance priority確定有多大的優(yōu)先級阻止自己變小咽安。
tip1:
content Hugging就是要維持當前view在它的optimal size(intrinsic content size),可以想象成給view添加了一個額外的width constraint蓬推,此constraint試圖保持view的size不讓其變大:
view.width <= optimal sizecontent Hugging默認為250.
tip2:
Content Compression Resistance就是要維持當前view在他的optimal size(intrinsic content size)妆棒,可以想象成給view添加了一個額外的width constraint,此constraint試圖保持view的size不讓其變蟹蟹:
view.width >= optimal sizeContent Compression Resistance默認優(yōu)先級為750.
3糕珊、AutoLayout 與 UIScrollView的相遇
a、首先給scrollview加上高和上左右的約束
b毅糟、再給image加上高和上左右的約束红选,放在scrollview中
但是有問題?
問題的原因:
我們知道UIScrollView最重要的就是其contentSize的寬高了姆另,如果這個無法確定喇肋,那scrollview就無法知曉可以滾動查看的區(qū)域。其實這僅僅是表象迹辐,IB不會因為contentSize的可見區(qū)域不確定而抱怨蝶防,因為它會有一個默認的可見區(qū)域就是其bounds,其實IB真正抱怨的是其內(nèi)部的subViews的布局對于它的依賴,比如我們看image相對于上明吩、左间学、右的約束都相對于scrollview的。scrollview內(nèi)部的subViews的約束全依賴于scrollview,這樣子的話印荔,問題就來了低葫,Scrollview和image一樣都會根據(jù)內(nèi)容調(diào)整其contentSize(autolayout布局模式中,image這種控件都會根據(jù)內(nèi)容對自身寬高進行調(diào)整),如果Scrollview要根據(jù)其subviews來調(diào)整自身的contentsize,而其subviews又要根據(jù)scrollview的contentsize調(diào)整自身的布局仍律,是不是就矛盾了氮采,就成了相互依賴了。
所以IB要求UIScrollview(當然包括繼承于它的UITableview染苛、UIWebview這些控件)的contentSize必須在布局時能夠確定鹊漠。
解決方法:
1主到、創(chuàng)建一個空白的UIViewController
2、將UIScrollView添加到UIView控件中躯概,并設置UIScrollView針對父視圖UIView的constraints(Leading/trailling/top/bottom = 0 || Leading/trailling/top= 0 + height=X )
3登钥、最主要的來了,添加UIView控件到UIScrollView中娶靡。牧牢。
(1)并改名為ContentView....(UIScrollView主要是靠子視圖來實現(xiàn)autolayout的高度和寬度的計算)
(2)然后設置ContentView的針對父視圖UIScrollView的 constraints
1、Leading/trailling/top= 0
2姿锭、bottom = 1
3塔鳍、equal height / equal width (ContentView的高度和寬度 與 UIScrollView相等)
4、設置equal height的優(yōu)先級 priority 小于 剛才設置的bottom的優(yōu)先級(該bottom的是ContentView針對UIScrollView的constraints),這里設置priority=999.
這里需要注意
第一:為什么 bottom =1 而不是 bottom = 0呻此。在實際開發(fā)中轮纫,如果為0,并且ContentView中的內(nèi)容高度不超過屏幕的高度時焚鲜,uiscrollview不能下上拉動掌唾。
第二:要實現(xiàn)ContentView 的高度自適應為uiscrollview的contentSize的高度,需要ContentView中的子視圖有明確的top與bottom忿磅,用來讓autolayout計算出ContentView的實際高度.
第三:為什么要設置equal height 的優(yōu)先級糯彬。。葱她。我們來寫個公式更容易理解
因為scrollview.height = uiview.height
又因為ContentView.height = scrollview.height - 1
所以ContentView.height != scrollView.height
也就是不能實現(xiàn)equal height 這個constraints撩扒。。會報錯吨些。
只要調(diào)整一下優(yōu)先級就可以解決這個問題,出現(xiàn)沖突却舀,優(yōu)先適應ContentView的高度....現(xiàn)在你可以在ContentView上添加你想添加的控件,但記住如果你要添加的控件已經(jīng)超出了屏幕的高度锤灿,你需要給ContentView里面的子控件加上bottom 和 top(不超過你也可以添加),這樣autolayout才能計算出ContentView的高度挽拔,并將這個高度賦給UIScrollView的ContentSize,實現(xiàn)自適應高度。還需要注意一點就是如果最下面的控件已經(jīng)超出界面外了但校,那么在添加bottom to ContentView的這個約束時螃诅,XCode默認是-xxx的,這個時候如果在模擬器上運行的話状囱,可以看到還是滑動不到最下面去术裸。所以要把這個約束值改為0或者大于0.
tip
如果代碼中設置了self.automaticallyAdjustsScrollViewInsets = NO;,那么則需要把ContentView中的最下面的控件的bottom to ContentView 約束+44.導航欄的高度亭枷。ContentView中如果使用UILabel袭艺,要給uilabel明確的height constraint,這樣auto layout才能計算出高度。
4叨粘、遇到過的小挫折
需求描述
首先這個頁面已經(jīng)布好局噠猾编。有一個scrollview瘤睹,scrollview里面有一個contentview,都已經(jīng)布局好噠答倡。
然后要往里面增加一個bannner轰传,這個banner距l(xiāng)astlabel為20,距superview的bottom是10瘪撇。
最后這個banner表示不是常駐居民获茬,要求出現(xiàn)時如果屏幕顯示不全求滾動,不出現(xiàn)時如果屏幕顯示完全不滾動倔既。
解決思路描述
鄙人思路一:直接把banner丟ContentView里面恕曲。
鄙人否決一:由于頁面的ContentView是與屏幕等heigh的,所以當加入banner后ContentView里面的子控件的高度和大于屏幕的高度就報錯渤涌。
鄙人思路二:根據(jù)思路一直接把banner的height設為0佩谣,IB就不會報錯啦,再在運行時把banner的height設為X歼捏。
鄙人否決二:于是乎,如圖所示笨篷,ContentView為了不讓它所以子控件的高度和超過自己的預定高度瞳秽,ContentView把banner壓扁了。率翅。练俐。。
在經(jīng)過幾番思想的掙扎之后冕臭,終于尋找到了解決之道腺晾,GOOD!
鄙人思路:直接把banner丟scrollview里面辜贵,讓banner與ContentView并排悯蝉。
鄙人解析:scrollview.contentView.height = contentView.height + bannner.height。所以只要contentView.height與bannner.height是實值IB就不會有問題啦托慨。
此處有演示小demo
https://github.com/HFavour/ShowTest.git
demo中有兩個小拓展鼻由。
俗話說,正在精通的技術已經(jīng)融化在思維中厚棵。蕉世。
所以。婆硬。狠轻。
后來。彬犯。向楼。查吊。我仿佛只記住了那一個公式。蜜自。菩貌。
最后,附上本文的參考鏈接:
http://www.reibang.com/p/f3c0f040c07a
http://www.reibang.com/p/25ddadddae06
http://www.reibang.com/p/248c5ed719ec