私は同様の問題を抱えていましたが、このスレッドはそれを乗り越えるための大きな助けになりました.
erurainon からの回答は私を正しい軌道に乗せましたが、少し異なる回答を提案したいと思います。アニメーション化されたトランジションの代わりにジャンプがまだあったため、erurainon から提案されたコードは機能しませんでした。cnotethegr8 が提供するリンクから、実用的な答えが得られました。
自動レイアウト ガイド
https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/AutolayoutPG/AutoLayoutbyExample/AutoLayoutbyExample.html (ページの一番下まで)。
erurainon による回答とのいくつかの違い:
- アニメーション メソッドを呼び出す前に (myView の setNeedsUpdateConstraints の代わりに)、コンテナー ビューで layoutIfNeeded を呼び出します。
- アニメーション ブロックに新しい制約を設定します。
- myView ではなく、アニメーション メソッドのコンテナー ビューで (制約を設定した後)、layoutIfNeeded を呼び出します。
これは、上記のリンクで Apple が提案したパターンに従います。
例
ボタンをクリックするだけで特定のビューを閉じたり、展開したりして、特定のビューをアニメーション化したいと考えていました。私は自動レイアウトを使用していて、コードに寸法 (私の場合は高さ) をハードコーディングしたくないので、viewDidLayoutSubviews で高さをキャプチャすることにしました。autolayout を使用する場合は、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
// ...
}
必要に応じて、transitionWithView の代わりに animateWithDuration を使用できます。
お役に立てれば。