原文來(lái)自這里,已將錯(cuò)誤地方修正,并將??重新上穿。
效果

在沒有autoLayout之前,如果你想移動(dòng)一個(gè)view,frame就會(huì)派出他兩個(gè)小弟origin或者size來(lái)對(duì)你大喊@"你動(dòng)我下試試!"。當(dāng)然,frame、bounds和center都是UIView的屬性,所以當(dāng)你真的動(dòng)了他們,UIView是不會(huì)作罷甘休的。所以你知道為啥用戶能看到一系列的動(dòng)畫了吧,UIView想削你呢。
如果你開始用autoLayout了,很快你就發(fā)現(xiàn)你不用親手去處理frame(或者bounds或者center)了。你可以叫約束去搞他。這篇文章就是通過一個(gè)簡(jiǎn)單的栗子,來(lái)告訴你怎么用約束搞點(diǎn)事情出來(lái)。額,確切的說(shuō)是搞出一個(gè)簡(jiǎn)單的動(dòng)畫效果。
開始
為了簡(jiǎn)單明了,我們只用兩個(gè)視圖。一個(gè)黃色視圖(以下簡(jiǎn)稱黃圖)和一個(gè)藍(lán)色視圖(以下簡(jiǎn)稱藍(lán)圖)。在"普通"模式下,我們只看到黃圖。在"五彩繽紛"模式下,藍(lán)色和黃色視圖都能看到。

設(shè)置基本約束
一開始,我在IB上拖出視圖,拉上約束。這個(gè)時(shí)候倆視圖都是可見的。
黃圖有五個(gè)約束:左邊相對(duì)父視圖間隔,右邊相對(duì)藍(lán)圖間隔,上邊相對(duì)switch間隔,下邊相對(duì)父視圖間隔,以及和藍(lán)圖寬度相等約束。

藍(lán)圖和黃圖的約束差不多,除了藍(lán)圖是右邊相對(duì)父視圖間隔。

非必需約束優(yōu)先級(jí)
在只有黃圖可見的時(shí)候,我們需要加另一個(gè)約束,也就是它右側(cè)相對(duì)父視圖的間隔約束。如果在上面我加上這個(gè)約束,那么他就和那個(gè)"右側(cè)相對(duì)藍(lán)圖約束"沖突了,因?yàn)樗麄z同時(shí)有優(yōu)先級(jí)1000。為了避免沖突以及移動(dòng)藍(lán)圖,我們可以改變一下黃藍(lán)圖間隔的那個(gè)約束的優(yōu)先級(jí)。
必需約束優(yōu)先級(jí)是這個(gè)UILayoutPriorityRequired(1000),你不能在運(yùn)行時(shí)改變一個(gè)必需約束的優(yōu)先級(jí)。優(yōu)先級(jí)比UILayoutPriorityRequired小的,就是一個(gè)可選或者非必需的約束,類似這種,只要你別把優(yōu)先級(jí)設(shè)置為UILayoutPriorityRequired,你就可以改。
所以首先,我們把藍(lán)圖右側(cè)相對(duì)父視圖約束的優(yōu)先級(jí)搞低一點(diǎn),搞到750.

然后我們?cè)诮o黃圖加一個(gè)它右側(cè)相對(duì)父視圖的約束(就像上面提到的),優(yōu)先級(jí)也搞到750.

把約束拖出來(lái)!
為了在運(yùn)行時(shí)改變藍(lán)圖右側(cè)約束我們得先把這個(gè)約束拖到代碼中。你也可以像這樣拖任意的約束出來(lái)。(就像把控件關(guān)聯(lián)到代碼中一樣,選中約束,按Ctrl拖)
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *blueViewConstraint;
為了確保我們把藍(lán)圖推出屏幕,我們也得調(diào)整黃圖右邊到父視圖的的間隔約束,所以我們把這個(gè)約束也整到代碼中。
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *viewSpacingContraint;
更新約束
現(xiàn)在可以很容易的寫一個(gè)方法來(lái)根據(jù)模式開關(guān)設(shè)置藍(lán)圖約束想要的優(yōu)先級(jí)。
-(void)updateConstraintsForMode {
if (self.modeSwitch.isOn) {
self.viewSpacingContraint.constant = 8.0;
self.blueViewConstraint.priority = UILayoutPriorityDefaultHigh+1;
} else {
self.viewSpacingContraint.constant = self.view.frame.size.width;
self.blueViewConstraint.priority = UILayoutPriorityDefaultHigh-1;
}
}
我們?cè)趕toryboard中把黃圖右側(cè)相對(duì)父視圖的約束也設(shè)定了優(yōu)先級(jí)UILayoutPriorityDefaultHigh(750)。為了使藍(lán)圖可見,我們需要把藍(lán)圖的右側(cè)約束優(yōu)先級(jí)設(shè)定的比750高一些,而隱藏起藍(lán)圖時(shí)我們得把它設(shè)定的低一些。
請(qǐng)注意!看黑板!我們要給黃圖右邊到父試圖的間隔設(shè)定一個(gè)大點(diǎn)的值(我這里用的屏幕寬度)以確保藍(lán)圖被推出右側(cè)邊界。
我們?cè)谝晥D第一次加載時(shí)也應(yīng)該配置下約束。
-(void)viewDidLoad {
// ...
[self updateConstraintsForMode];
}
動(dòng)起來(lái)
現(xiàn)在萬(wàn)事俱備只欠東風(fēng)了,我們現(xiàn)在只需要輕輕的撥動(dòng)一下模式開關(guān),既可動(dòng)起來(lái)了,蘋果的Auto Layout Guide描述了autoLayout搞動(dòng)畫的基本方法,推薦的代碼如下:
[UIView animateWithDuration:1.0 animations:^{
// Make all constraint changes here
[containerView layoutIfNeeded];
}];
代碼
在我們的栗子中用上面的方法,就是這樣式的:
-(IBAction)enableMode:(UISwitch *)sender {
[UIView animateWithDuration:1.0 animations:^{
[self updateConstraintsForMode];
[self.view layoutIfNeeded];
}];
}