前言
春節(jié)快到了凉夯,挺久沒(méi)回家的,在帝都離回家的日子也越來(lái)越近采幌,反而覺(jué)得有些恐慌劲够,年前最后一篇了,寫(xiě)點(diǎn)關(guān)于cell屏幕適配的技巧吧休傍,希望能給大家?guī)?lái)點(diǎn)幫助征绎,這篇大都是操作性的,我盡可能截一些圖理解磨取,大家觀(guān)看的時(shí)候耐心加載圖片人柿,OK,廢話(huà)不多少說(shuō)忙厌,下面開(kāi)始凫岖。
正文
現(xiàn)在實(shí)踐中慢慢盡可能少的代碼去實(shí)現(xiàn)UI部分,大都使用IB去操作逢净,之前實(shí)現(xiàn)一些高度不統(tǒng)一cell哥放,而且可能某些控件隱藏或者顯示,都是拿到數(shù)據(jù)源通過(guò)代碼去計(jì)算每行cell的高度爹土,也比較耗費(fèi)時(shí)間甥雕,接下來(lái)就聊聊我是怎么用Auto Layout去實(shí)現(xiàn)的。
上面舉個(gè)簡(jiǎn)單例子胀茵,cell內(nèi)部只有兩個(gè)控件社露,一個(gè)ImageView和Label,說(shuō)下需求:
- 假設(shè)UI給的效果圖是6p的琼娘,圖片在6p上是100*100的峭弟,在別的屏幕按比例縮放。
- label的字?jǐn)?shù)不固定脱拼。
- label可能顯示或隱藏瞒瘸,cell需要根據(jù)label的顯示和隱藏去適應(yīng)高度。
先來(lái)一步步來(lái)實(shí)現(xiàn)上面三個(gè)需求....
一挪拟、子控件根據(jù)父控件比例縮放
1挨务、先在xib中拖出上面兩個(gè)控件击你,選中圖片玉组,設(shè)置距離cell上面和左邊的邊距都為10谎柄,圖片的x和y已經(jīng)確定了,這里就不上圖了惯雳,大家應(yīng)該知道朝巫。
2、為了圖片不變形石景,先設(shè)置圖片相對(duì)自身的寬高比劈猿,選中圖片,往自身拖出約束潮孽,選擇Aspect Ratio
再選中剛剛添加的約束揪荣,在右邊欄按圖編輯好對(duì)應(yīng)寬高比,這里設(shè)置寬高1:1往史。
3仗颈、接下來(lái)是按屏幕寬度縮放,選中圖片拖向它所在的父控件椎例,這里的父控件就是contentView挨决,同樣選擇Aspect Ratio。
選中約束還是在右邊欄去編輯好订歪,如下圖脖祈,這里是相對(duì)6p的效果圖,所以設(shè)置100:414刷晋,需求的第一步已經(jīng)完成了盖高。
二、Label內(nèi)容自適應(yīng)
1眼虱、還是先設(shè)置Label上部距離圖片底部邊距以及距離父控件左或舞、右側(cè)邊距,這三個(gè)約束已經(jīng)給定label內(nèi)容顯示的最大寬度蒙幻。
2映凳、很重要的一步,選中l(wèi)abel在上面欄點(diǎn)擊Editor邮破,選中Size to Fit Content诈豌,或者使用快捷鍵com = ,意味著label的尺寸根據(jù)它的內(nèi)容去適應(yīng)抒和,根據(jù)你上一步給定的那個(gè)寬度去折行矫渔,同時(shí)記得label的行數(shù)設(shè)置為0。
3摧莽、很顯然現(xiàn)在運(yùn)行cell的高度是不會(huì)根據(jù)內(nèi)容適應(yīng)高度的庙洼,再label添加一個(gè)下面距離父控件的約束,這里也是設(shè)為10的邊距,現(xiàn)在
cell的高度 = 圖片的上邊距 + 圖片高度 + 文字和圖片邊距 + 文字高度 + 文字下面距離父控件邊距油够,是不是有些像我們平時(shí)使用Auto Layout設(shè)置scrollView的約束蚁袭,你可以這么理解,父控件的內(nèi)容根據(jù)子控件去撐滿(mǎn)石咬。
最后還需要一行代碼揩悄,也是最關(guān)鍵的一步,設(shè)置tableView的estimatedRowHeight鬼悠,顧名思義就是預(yù)設(shè)的行高删性,你可以隨意設(shè)置一個(gè)值,當(dāng)cell滑動(dòng)時(shí)會(huì)去計(jì)算出真實(shí)的行高焕窝,這樣前兩個(gè)需求就做完了蹬挺,Auto Layout已經(jīng)幫我們計(jì)算好了行高,是不是很方便才寫(xiě)了一行代碼它掂,比較遺憾的事這個(gè)方法適用比較簡(jiǎn)單的cell汗侵,復(fù)雜的用此方法可能會(huì)有卡頓問(wèn)題,所以根據(jù)復(fù)雜程度使用群发。
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
self.example1TableView.estimatedRowHeight = 100;
}
三晰韵、設(shè)置約束優(yōu)先級(jí)
先簡(jiǎn)單介紹一下約束優(yōu)先級(jí),具有優(yōu)先級(jí)1000(UILayoutPriorityRequired)的約束為強(qiáng)制約束(Required Constraint)熟妓,也就是必須要滿(mǎn)足的約束雪猪;優(yōu)先級(jí)小于1000的約束為可選約束(Optional Constraint)。默認(rèn)創(chuàng)建的是強(qiáng)制約束起愈。它分為
高優(yōu)先級(jí):UILayoutPriorityDefaultHigh只恨,
低優(yōu)先級(jí):UILayoutPriorityDefaultLow,
內(nèi)置的最低優(yōu)先級(jí):UILayoutPriorityFittingSizeLevel
typedef float UILayoutPriority;
static const UILayoutPriority UILayoutPriorityRequired NS_AVAILABLE_IOS(6_0) = 1000; // A required constraint. Do not exceed this.
static const UILayoutPriority UILayoutPriorityDefaultHigh NS_AVAILABLE_IOS(6_0) = 750; // This is the priority level with which a button resists compressing its content.
static const UILayoutPriority UILayoutPriorityDefaultLow NS_AVAILABLE_IOS(6_0) = 250; // This is the priority level at which a button hugs its contents horizontally.
static const UILayoutPriority UILayoutPriorityFittingSizeLevel NS_AVAILABLE_IOS(6_0) = 50; // When you send -[UIView systemLayoutSizeFittingSize:], the size fitting most closely to the target size (the argument) is computed. UILayoutPriorityFittingSizeLevel is the priority level with which the view wants to conform to the target size in that computation. It's quite low. It is generally not appropriate to make a constraint at exactly this priority. You want to be higher or lower.
現(xiàn)在我們想當(dāng)label隱藏時(shí)圖片距離cell的底部也為10抬虽,現(xiàn)在就需要再添加一條圖片距離cell底部為10的下邊距官觅,這時(shí)候我們發(fā)現(xiàn)會(huì)有沖突,選中這條約束把優(yōu)先級(jí)設(shè)置得低一些阐污,會(huì)發(fā)現(xiàn)沖突消失了休涤,約束變成了虛線(xiàn),把之前圖片相對(duì)label的邊距的約束拖到.h中作為cell的屬性笛辟。
在tableview代理方法里面判斷l(xiāng)abel顯示或隱藏來(lái)修改優(yōu)先級(jí)
cell.imageBotton.priority = cell.label.hidden ? UILayoutPriorityDefaultLow : UILayoutPriorityDefaultHigh;
當(dāng)label隱藏時(shí)把優(yōu)先級(jí)設(shè)置為UILayoutPriorityDefaultLow功氨,顯示時(shí)設(shè)置UILayoutPriorityDefaultHigh,只要是比圖片底部相對(duì)父控件邊距那條約束低就行了手幢。
這里有一個(gè)注意點(diǎn):
- 不允許將優(yōu)先級(jí)由小于1000的值改為1000捷凄,例如,如果將優(yōu)先級(jí)由250修改為1000围来,則會(huì)拋出異常跺涤,控制臺(tái)會(huì)打印以下:
所有操作都做完了匈睁,現(xiàn)在運(yùn)行效果如下:
最后是這次的代碼:
https://github.com/ShelinShelin/AutoLayoutDemo
之前的一些例子請(qǐng)點(diǎn)擊:
https://github.com/ShelinShelin 歡迎右上角??Star,謝謝桶错!