我也有类似的问题,这条线索是一个很大的帮助,让它过去。
erurainon的答案让我找到了正确的方向,但我想提出一个稍微不同的答案。来自erurainon的建议代码并不适合我,因为我仍然有一个跳跃而不是一个动画过渡。由cnotethegr8提供的链接给了我工作的答案:
自动布局指南
https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/AutolayoutPG/AutoLayoutbyExample/AutoLayoutbyExample.html(一直到页面底部)。
与erurainon的答案有几点不同:
在调用动画方法之前调用容器视图上的layoutIfNeeded(而不是myView上的setNeedsUpdateConstraints)。
在动画块中设置新的约束。
在animations方法的容器视图上调用layoutIfNeeded(在设置约束之后),而不是在myView上。
这将遵循苹果在上面链接中建议的模式。
一个例子
我想要动画一个特定的视图,在点击按钮时关闭或展开它。由于我使用自动布局,并不想硬编码任何尺寸(在我的情况下高度)在代码中,我决定在viewDidLayoutSubviews中捕获高度。当使用自动布局时,你需要使用这个方法而不是viewWillAppear。由于viewDidLayoutSubviews可能会被调用很多次,我使用BOOL来让我知道我的初始化的第一次执行。
// Code snippets
@property (weak, nonatomic) IBOutlet UIView *topView; // Container for minimalView
@property (weak, nonatomic) IBOutlet UIView *minimalView; // View to animate
@property (nonatomic) CGFloat minimalViewFullHeight; // Original height of minimalView
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *minimalViewHeightConstraint;
@property (nonatomic) BOOL executedViewDidLayoutSubviews;
- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
// First execution of viewDidLayoutSubviews?
if(!self.executedViewDidLayoutSubviews){
self.executedViewDidLayoutSubviews = YES;
// Record some original dimensions
self.minimalViewFullHeight = self.minimalView.bounds.size.height;
// Setup our initial view configuration & let system know that
// constraints need to be updated.
self.minimalViewHeightConstraint.constant = 0.0;
[self.minimalView setNeedsUpdateConstraints];
[self.topView layoutIfNeeded];
}
}
调整整个动作片段的大小
// An action to close our minimal view and show our normal (full) view
- (IBAction)resizeFullAction:(UIButton *)sender {
[self.topView layoutIfNeeded];
[UIView transitionWithView:self.minimalView
duration:1.0
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^{
self.minimalViewHeightConstraint.constant = 0.0;
// Following call to setNeedsUpdateConstraints may not be necessary
[self.minimalView setNeedsUpdateConstraints];
[self.topView layoutIfNeeded];
} completion:^(BOOL finished) {
;
}];
// Other code to show full view
// ...
}
调整小动作片段的大小
// An action to open our minimal view and hide our normal (full) view
- (IBAction)resizeSmallAction:(UIButton *)sender {
[self.topView layoutIfNeeded];
[UIView transitionWithView:self.minimalView
duration:1.0
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^{
self.minimalViewHeightConstraint.constant = self.minimalViewFullHeight;
[self.minimalView setNeedsUpdateConstraints];
[self.topView layoutIfNeeded];
} completion:^(BOOL finished) {
;
}];
// Other code to hide full view
// ...
}
如果你愿意,你可以使用animateWithDuration代替transitionWithView。
希望这能有所帮助。