Autolayout約束動(dòng)畫

原文來(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è)置約束

設(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.

調(diào)整約束優(yōu)先級(jí)

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

右邊圖相對(duì)父試圖的優(yōu)先級(jí)

把約束拖出來(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];
  }];
 }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容