2012-11-08 169 views
113

我從來沒有與自動佈局約束之前。我正在創建一個小型的新應用,並注意到NIB的視圖默認爲自動佈局。所以,我想我會藉此機會它,並試圖找出蘋果去哪裏與此。iOS:如何動畫到新的自動佈局約束(高度)

第一個挑戰:

我需要調整的的MKMapView,我想它動畫到新的位置。如果我這樣做的方式,我已經習慣了:

[UIView animateWithDuration:1.2f 
    animations:^{ 
     CGRect theFrame = worldView.frame; 
     CGRect newFrame = CGRectMake(theFrame.origin.x, theFrame.origin.y, theFrame.size.width, theFrame.size.height - 170); 
     worldView.frame = newFrame; 
}]; 

...那麼的MKMapView將「捕捉」恢復到原來的高度,只要兄弟姐妹視圖被更新(在我的情況下,一個UISegmentedControl的標題被更新[myUISegmentedControl setTitle:newTitle forSegmentAtIndex:0])。

所以,我我想要做的是從等於父視圖的HIGHT到可相對於UISegmentedControl頂部改變的MKMapView的限制,這覆蓋:V:[MKMapView]-(16)-[UISegmentedControl]

我想要的是MKMapView高度縮短,以便顯示地圖視圖下的一些控件。要做到這一點我認爲我需要將約束從固定的全尺寸視圖更改爲底部約束到UISegmentedControl的頂部...我希望它動畫視圖縮小到新的大小。

這是怎麼回事?

編輯 - 這個動畫是動畫雖然視圖的底部不會馬上拉昇170:

[UIView animateWithDuration:1.2f 
     animations:^{ 
      self.nibMapViewConstraint.constant = -170; 

    }]; 

nibMapViewConstraint連線了在IB的底部垂直空間約束。

+1

我知道,你可以很容易地改變一個[UIView的animateWithDuration約束的恆定值containerView的高度約束。 。]塊來爲高度變化設置動畫。您需要爲該約束創建一個IBOutlet並將其掛接到xib中,否則,如果您使用代碼創建它(或通過所有約束來查找它),請保留對其的引用。不知道如何動畫relatedBy的變化,但我讀過,你應該只改變常量而不是其他值的約束(對於其他值,創建一個新的約束)。 – yuf

+0

嗯。我以爲我可以但我不是動畫。它改變,成功,並在動畫塊,但* *不*動畫!?! – Meltemi

+0

發現我的答案在這裏: Meltemi

回答

165

更新約束後:

[UIView animateWithDuration:0.5 animations:^{[self.view layoutIfNeeded];}]; 

替換self.view與到包含視圖的引用。

+4

可用於視圖本身,但是對該視圖有限制只是立即行動。我該怎麼辦? ty – dietbacon

+7

您還需要在這些視圖上調用佈局。但是它並不能正常工作,因爲這會使視圖刷新動畫。只有在其他視圖中,你如何使約束調整動畫化? – ngb

+3

**注意:**如果使用'UIViewAnimationOptionBeginFromCurrentState',佈局約束將被設置爲* BEFORE *動畫! – Robert

11

從蘋果本身有一個非常好的教程,解釋如何使用自動佈局動畫。 按照此link,然後找到名爲「通過示例自動佈局」的視頻 它提供了一些有關自動佈局的有趣內容,最後一部分是關於如何使用動畫。

3

我製作了this small demo available。它以簡單的例子顯示了自動佈局約束如何改變和動畫。只需看看。

82

這適用於我(iOS7和iOS8 +)。點擊您想要調整的自動佈局約束(在界面構建器中,例如頂部約束)。接下來讓它成爲一個IBOutlet;

@property (strong, nonatomic) IBOutlet NSLayoutConstraint *topConstraint; 

動畫向上;

self.topConstraint.constant = -100;  
    [self.viewToAnimate setNeedsUpdateConstraints]; 
    [UIView animateWithDuration:1.5 animations:^{ 
     [self.viewToAnimate layoutIfNeeded]; 
    }]; 

動畫回到原來的地方

self.topConstraint.constant = 0;  
    [self.viewToAnimate setNeedsUpdateConstraints]; 
    [UIView animateWithDuration:1.5 animations:^{ 
     [self.viewToAnimate layoutIfNeeded]; 
    }]; 
+2

哇!這實際上確實有用!這個答案讓我大開眼界。謝謝你太多了! - Erik –

+2

@ErikvanderNeut它也適合我,很高興它有幫助。我將從現在開始製作動畫約束,而不是幀位置。 – DevC

1

大多數人使用自動版式佈局項目對他們的意見和修改佈局約束創建動畫。

一個簡單的方法來做到這一點,沒有太多的代碼是創建你想要在故事板中動畫的UIView,然後創建一個隱藏的UIView,你想UIView結束。您可以在xcode中使用預覽來確保兩個UIViews都是您希望它們成爲的地方。之後,隱藏結尾的UIView並交換佈局約束。

如果您不想親自編寫,有一個用於交換稱爲SBP的佈局約束的podfile。

Here's a tutorial

0

無需在使用KVConstraintExtensionsMaster庫中的任何視圖中使用約束的更多IBOutlet reference,而不是這個,你可以直接accessupdate已應用約束或者通過應用或ProgrammaticallyInterface Builder。該庫還管理着NSLayoutConstraintCumulative行爲。

要在containerView

CGFloat height = 200; 
[self.containerView applyHeightConstrain:height]; 

增加高度約束要更新動畫

[self.containerView accessAppliedConstraintByAttribute:NSLayoutAttributeHeight completion:^(NSLayoutConstraint *expectedConstraint){ 
     if (expectedConstraint) { 
      expectedConstraint.constant = 100; 

      /* for the animation */ 
      [self.containerView updateModifyConstraintsWithAnimation:NULL]; 
     } 
    }];