[ios] 制約の変更をどのようにアニメーション化するのですか?


Answers

私は提供された答えを感謝しますが、私はそれをもう少し取ることはいいと思う。

ドキュメンテーションの基本ブロックアニメーション

[containerView layoutIfNeeded]; // Ensures that all pending layout operations have been completed
[UIView animateWithDuration:1.0 animations:^{
     // Make all constraint changes here
     [containerView layoutIfNeeded]; // Forces the layout of the subtree animation block and then captures all of the frame changes
}];

実際にはこれは非常に単純なシナリオです。 updateConstraintsメソッドを使用してサブビュー制約をアニメーション化する場合はどうすればよいですか?

サブビューを呼び出すアニメーションブロックupdateConstraintsメソッド

[self.view layoutIfNeeded];
[self.subView setNeedsUpdateConstraints];
[self.subView updateConstraintsIfNeeded];
[UIView animateWithDuration:1.0f delay:0.0f options:UIViewAnimationOptionLayoutSubviews animations:^{
    [self.view layoutIfNeeded];
} completion:nil];

updateConstraintsメソッドはUIViewサブクラスでオーバーライドされ、メソッドの最後にsuperを呼び出す必要があります。

- (void)updateConstraints
{
    // Update some constraints

    [super updateConstraints];
}

AutoLayout Guideは多くのことを望みますが、読む価値があります。 私自身はこれを、 UISwitch一部として使用しています。これは、 UITextFieldのペアを使用してサブビューを切り替え、シンプルで繊細な崩壊アニメーション(0.2秒)を使用しています。 サブビューの制約は、上記のUIViewサブクラスのupdateConstraintsメソッドで処理されています。

Question

私はAdBannerView古いアプリを更新しています。広告がない場合は、画面から外れます。 広告があるとき、画面上をスライドします。 基本的なもの。

古いスタイル、私はアニメーションブロックでフレームを設定します。 新しいスタイルでは、Y位置を決定する制約にIBOutletがあります。この場合、それはスーパービューの底からの距離であり、定数を変更します。

- (void)moveBannerOffScreen {
    [UIView animateWithDuration:5
             animations:^{
                          _addBannerDistanceFromBottomConstraint.constant = -32;
                     }];
    bannerIsVisible = FALSE;
}

- (void)moveBannerOnScreen {
    [UIView animateWithDuration:5
             animations:^{
                         _addBannerDistanceFromBottomConstraint.constant = 0;
             }];
    bannerIsVisible = TRUE;
}

そして、バナーは予想どおりに動きますが、アニメーションはありません。

更新:アニメーションをカバーするWWDC12のビデオ「 マスターレイアウト自動レイアウトのベストプラクティス 」を再見ました。 CoreAnimationを使用して制約を更新する方法について説明します。

私は次のコードで試したが、まったく同じ結果を得る。

- (void)moveBannerOffScreen {
    _addBannerDistanceFromBottomConstraint.constant = -32;
    [UIView animateWithDuration:2
                     animations:^{
                         [self.view setNeedsLayout];
                     }];
    bannerIsVisible = FALSE;
}

- (void)moveBannerOnScreen {
    _addBannerDistanceFromBottomConstraint.constant = 0;
    [UIView animateWithDuration:2
                     animations:^{
                         [self.view setNeedsLayout];
                     }];
    bannerIsVisible = TRUE;
}

私は何度もチェックをしており、これはメインスレッドで実行されています。




Xcode 8.3.3を使用したSwift 3の作業とテスト済みのソリューション:

self.view.layoutIfNeeded()
self.calendarViewHeight.constant = 56.0

UIView.animate(withDuration: 0.5, delay: 0.0, options: UIViewAnimationOptions.curveEaseIn, animations: {
        self.view.layoutIfNeeded()
    }, completion: nil)

self.calendarViewHeightはcustomView(CalendarView)に参照される制約です。 self.viewでは.layoutIfNeeded()を呼び出し、self.calendarViewではそうではありません

この助けを願っています。




ワーキングソリューション100% Swift 3.1

私はすべての答えを読んで、私がすべてのアプリケーションで正しく使っていたコードや階層を共有したいと思っています。ここで解決されているソリューションもあります。

self.view.layoutIfNeeded() // Force lays of all subviews on root view
UIView.animate(withDuration: 0.5) { [weak self] in // allowing to ARC to deallocate it properly
       self?.tbConstraint.constant = 158 // my constraint constant change
       self?.view.layoutIfNeeded() // Force lays of all subviews on root view again.
}



// Step 1, update your constraint
self.myOutletToConstraint.constant = 50; // New height (for example)

// Step 2, trigger animation
[UIView animateWithDuration:2.0 animations:^{

    // Step 3, call layoutIfNeeded on your animated view's parent
    [self.view layoutIfNeeded];
}];



迅速なソリューション:

yourConstraint.constant = 50
UIView.animateWithDuration(1, animations: yourView.layoutIfNeeded)



これに関する記事がありhttp://weblog.invasivecode.com/post/42362079291/auto-layout-and-core-animation-auto-layout-washttp://weblog.invasivecode.com/post/42362079291/auto-layout-and-core-animation-auto-layout-was : http://weblog.invasivecode.com/post/42362079291/auto-layout-and-core-animation-auto-layout-was

それで、彼は次のようにコード化しました:

- (void)handleTapFrom:(UIGestureRecognizer *)gesture {
    if (_isVisible) {
        _isVisible = NO;
        self.topConstraint.constant = -44.;    // 1
        [self.navbar setNeedsUpdateConstraints];  // 2
        [UIView animateWithDuration:.3 animations:^{
            [self.navbar layoutIfNeeded]; // 3
        }];
    } else {
        _isVisible = YES;
        self.topConstraint.constant = 0.;
        [self.navbar setNeedsUpdateConstraints];
        [UIView animateWithDuration:.3 animations:^{
            [self.navbar layoutIfNeeded];
        }];
    }
}

それが役に立てば幸い。




Related