我遇到了类似的问题,这个线程对克服它很有帮助。
erurainon 的回答让我走上了正轨,但我想提出一个稍微不同的答案。erurainon 建议的代码对我不起作用,因为我仍然有一个跳跃而不是动画过渡。cnotethegr8 提供的链接给了我有效的答案:
自动布局指南
https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/AutolayoutPG/AutoLayoutbyExample/AutoLayoutbyExample.html (一直到页面底部)。
与 erurainon 的答案有一些不同之处:
- 在调用动画方法之前在容器视图上调用 layoutIfNeeded(而不是 myView 上的 setNeedsUpdateConstraints)。
- 在动画块中设置新的约束。
- 在动画方法中(在设置约束之后)对容器视图调用 layoutIfNeeded,而不是在 myView 上调用。
这将遵循 Apple 在上面的链接中建议的模式。
一个例子
我想为特定视图设置动画,单击按钮即可关闭或展开它。由于我使用的是自动布局并且不想在代码中硬编码任何尺寸(在我的情况下为高度),我决定在 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。
希望这可以帮助。