web-dev-qa-db-ja.com

iOS 10でAutoLayout制約アニメーションの違いを処理しますか?

IOS 10 Beta 5(Beta 6を試そうとしています)では、AutoLayout制約アニメーションの動作が少し異なります。

たとえば、このアプローチは、以前のiOSリリースと同じようには機能しません。

[view addConstraints:@[constraints...]];

[view setNeedsUpdateConstraints];
[view layoutIfNeeded];

[UIView animateWithDuration:...
{
    /* adjust constraint here... */
    [view layoutIfNeeded]; // Only the adjusted constraints since previous layoutIfNeeded() call should animate change with duration.

} completion:{ ... }];

...私のテストでは、最初にaddConstraints()で追加された制約は、UIView animateWithDuration()ブロックを使用してiOS 10でalsoアニメーション化します...これまでのところ、ファンキー/望ましくない動作が発生しています。

たとえば、配列に左右の制約を設定すると(ただし、ブロックには垂直の制約が設定されます)、このアプローチでビュー全体が画面上で斜めにアニメートされます...完全に間違っています。

誰もがiOS 9(およびそれ以下)と10の両方でこれを正しく行う方法を知っていますか?

29
Ben Guild

ビュー自体ではなく、ビューのスーパービューでlayoutIfNeededを呼び出してみてください。

-

私は同様の問題を抱えていました。私のビューは、上から0の高さで、> 0の高さまで下にアニメーション化することになっています(つまり、(0、0、320、0)から(0、0、320、44))。

IOS 10でXcode 8を使用すると、アニメーションの動作が大きく異なります。ビューは、上から下にアニメートする代わりに、宛先フレームの垂直方向の中心から上下にアニメートします。

これを修正するには、ビュー自体でlayoutIfNeededを呼び出す代わりに、ビューのスーパービューで呼び出します。どういうわけか、動作が復元されました。

それが役に立てば幸い!


ドキュメントによると、layoutIfNeededはサブビューをレイアウトします(ただし、現在のビュー自体は考慮していません)。そのため、現在のビューのレイアウトを更新するには、スーパービューからlayoutIfNeededを呼び出す必要があります。

90
beebcon

以下の方法で:

[super viewDidLoad];

この行を書きます:

 [self.view layoutIfNeeded];
2
Rizwan Shaikh

小さな赤いビューのHとVを変更する小さなテストを行いました。

self.red_POS_H = NSLayoutConstraint.constraints(withVisualFormat: "H:|-90-[redView]", options: defaultOptions, metrics: nil, views: viewsDictionary)


self.red_POS_V = NSLayoutConstraint.constraints(withVisualFormat: "V:|-30-[redView]", options: defaultOptions, metrics: nil, views: viewsDictionary)

self.view.addConstraints(self.red_POS_V!)
self.view.addConstraints(self.red_POS_H!)

それをアニメーション化:

        // we hope is only one:
        let currV = self.red_POS_V![0]
        let currH = self.red_POS_H![0]


        UIView.animate(withDuration: 3) { 
            // Make all constraint changes here

            currV.constant = 100
            currH.constant = 300

            self.view.layoutIfNeeded() // Forces the layout of the subtree animation block and then captures all of the frame changes
        }

赤いビューが正しく移動しました。アニメーションの1行をコメントアウトすると、水平または垂直に機能します。

あなたがそれを必要とする場合、利用可能な小さなプロジェクト。

0
ingconti