我以前从未使用过自动布局约束。我有一个正在开发的小型新应用程序,并注意到 NIB 的视图默认为自动布局。所以,我想我会借此机会与它合作,并试图弄清楚苹果公司的发展方向。
第一个挑战:
我需要调整 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;
}];
...然后,只要兄弟视图更新(在我的情况下,UISegmentedControl 的标题正在更新 [myUISegmentedControl setTitle:newTitle forSegmentAtIndex:0]
),MKMapView 就会“捕捉”回其原始高度。
所以,我认为我想要做的是将 MKMapView 的约束从等于父视图的高度更改为相对于它 曾经的 UISegmentedControl 的顶部覆盖:V:[MKMapView]-(16)-[UISegmentedControl]
我想要的是缩短 MKMapView 的高度,以便显示地图视图下方的一些控件。为此,我认为我需要将约束从固定的全尺寸视图更改为底部被约束到 UISegmentedControl 顶部的约束......并且我希望它在视图缩小到新尺寸时进行动画处理。
怎么办?
编辑 - 虽然视图的底部确实立即向上移动了 170,但此动画没有动画:
[UIView animateWithDuration:1.2f
animations:^{
self.nibMapViewConstraint.constant = -170;
}];
并且 nibMapViewConstraint
在 IB 中连接到底部垂直空间约束。
更新约束后:
[UIView animateWithDuration:0.5 animations:^{[self.view layoutIfNeeded];}];
将 self.view
替换为对包含视图的引用。
这对我有用(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];
}];
苹果本身有一个非常好的教程,解释了如何使用带有自动布局的动画。按照这个link,然后找到名为“Auto layout by example”的视频,它提供了一些关于自动布局的有趣内容,最后一部分是关于如何使用动画。
大多数人使用自动布局在他们的视图上布局项目并修改布局约束以创建动画。
无需大量代码即可完成此操作的一种简单方法是创建要在 Storyboard 中制作动画的 UIView,然后在您希望 UIView 结束的位置创建隐藏的 UIView。您可以使用 xcode 中的预览来确保两个 UIView 都在您想要的位置。之后,隐藏结束 UIView 并交换布局约束。
如果您不想自己编写,有一个用于交换布局约束的 podfile,称为 SBP。
无需使用更多的 IBOutlet reference
约束,您可以直接 access
或 update
已应用的约束,由 Programmatically
或从 Interface Builder
应用到使用 KVConstraintExtensionsMaster
库的任何视图上。该库还管理 NSLayoutConstraint
的 Cumulative
行为。
在 containerView 上添加高度约束
CGFloat height = 200;
[self.containerView applyHeightConstrain:height];
用动画更新 containerView 的高度约束
[self.containerView accessAppliedConstraintByAttribute:NSLayoutAttributeHeight completion:^(NSLayoutConstraint *expectedConstraint){
if (expectedConstraint) {
expectedConstraint.constant = 100;
/* for the animation */
[self.containerView updateModifyConstraintsWithAnimation:NULL];
}
}];
UIViewAnimationOptionBeginFromCurrentState
,布局约束将在动画之前设置!layoutIfNeeded
,只需调用[[self.view superview] layoutIfNeeded];
UIViewAnimationOptionBeginFromCurrentState
。