23

この質問を説明するために、Github で非常に小さな Xcode プロジェクトを作成しました (2 つのクラス、11kb のダウンロード)。こちらの要点を参照するか、git clone git@gist.github.com:93982af3b65d2151672e.gitを使用してください。


次のシナリオを検討してください。「コンテナ ビュー」と呼ばれる私のカスタム ビューには、2 つの小さな正方形が含まれています。このスクリーンショットに示されている:

2 つの正方形の初期位置のスクリーンショット

青い四角は 22x22 ポイントUIViewのインスタンスで、赤い四角は 22x22 ポイントのCALayerインスタンスです。この質問の目的のために、外側のビューのフレームをアニメーション化しながら、2 つの正方形を外側のビューの右下隅に「貼り付ける」必要があります。

タイプ のデフォルト以外のイージング パラメータを使用して、UIViewのクラス メソッド内のコンテナ ビューのフレームを変更します。animateWithDuration:delay:options:animations:completion:UIViewAnimationCurveEaseOut

[UIView animateWithDuration:1.0 delay:0 
                    options:UIViewAnimationCurveEaseOut 
                 animations:^{ _containerView.frame = randomFrame; } 
                 completion:nil];

注:青の UIView と赤の CALayer のフレームは両方ともsetFrame:コンテナー ビューのオーバーライドされたメソッドで設定されますが、青の UIView のautoresizingMaskプロパティを UIView の柔軟な左マージンと上マージンに設定した場合、結果は同じになります。

結果のアニメーションでは、青い四角は意図したとおりに角に「くっついています」が、赤い四角はアニメーションのタイミングとイージングの両方を完全に無視しています。これは、Core Animation の暗黙的なアニメーション機能によるものだと思います。これは、これまで何度も私を助けてきた機能です。

2 つの正方形の非同期性を示すアニメーション シーケンスのスクリーンショットを次に示します。

赤い四角が「正しい」場所にないアニメーションの途中の 3 つのスクリーンショット

質問: 2 つのフレーム変更を同期して、赤い CALayer と青い UIView の両方が同じアニメーション期間とイージング カーブで移動し、1 つのビューであるかのように互いにくっつく方法はありますか?

PSもちろん、2つの正方形がくっつくという必要な視覚的結果は、たとえば両方のレイヤーをCALayersまたはUIViewsにするなど、さまざまな方法で実現できますが、実際の問題が含まれているプロジェクトには、 1 つは CALayer で、もう 1 つは UIView です。

4

2 に答える 2

10

終了位置が正しく、アニメーション後にビューとレイヤーが整列していると仮定しています。これはアニメーションとは関係なく、ジオメトリだけです。


CALayer ビューのレイヤーではないa のプロパティを変更すると(あなたの場合のように)、暗黙的に新しい値にアニメーション化されます。このアニメーションをカスタマイズするには、基本的なアニメーションのような明示的なアニメーションを使用できます。基本的なアニメーションでフレームを変更すると、次のようになります。

CABasicAnimation *myAnimation = [CABasicAnimation animationWithKeyPath:@"frame"];
[myAnimation setToValue:[NSValue valueWithCGRect:myNewFrame]];
[myAnimation setFromValue:[NSValue valueWithCGRect:[myLayer frame]]];
[myAnimation setDuration:1.0];
[myAnimation setTimingFunction:[CAMediaTimingFuntion functionWithName: kCAMediaTimingFunctionEaseOut]];

[myLayer setFrame:myNewFrame];
[myLayer addAnimation:myAnimation forKey:@"someKeyForMyAnimation"];

両方のアニメーションのタイミング関数と期間が同じ場合、それらは整列したままになります。

また、明示的なアニメーションは値を変更せず、アニメーションを追加して新しい値を設定する必要があることに注意してください (上記のサンプルのように)。


はい、同じ効果を得る方法はいくつかあります。1 つの例は、ビューとレイヤーを同じサブビューのサブビューにすることです (つまり、外側のフレームのサブビューです)。

編集

UIView アニメーションを明示的なアニメーションと簡単にグループ化することはできません。アニメーション グループを使用することもできませんが (異なるレイヤーに適用しているため)、CATransaction を使用することはできます。

[CATransaction begin];
[CATransaction setAnimationDuration:1.0];
[CATransaction setAnimationTimingFunction:[CAMediaTimingFuntion functionWithName: kCAMediaTimingFunctionEaseOut]];

// Layer animation
CABasicAnimation *myAnimation = [CABasicAnimation animationWithKeyPath:@"frame"];
[myAnimation setToValue:[NSValue valueWithCGRect:myNewFrame]];
[myAnimation setFromValue:[NSValue valueWithCGRect:[myLayer frame]]];

[myLayer setFrame:myNewFrame];
[myLayer addAnimation:myAnimation forKey:@"someKeyForMyAnimation"];

// Outer animation
CABasicAnimation *outerAnimation = [CABasicAnimation animationWithKeyPath:@"frame"];
[outerAnimation setToValue:[NSValue valueWithCGRect:myNewOuterFrame]];
[outerAnimation setFromValue:[NSValue valueWithCGRect:[outerView frame]]];

[[outerView layer] setFrame:myNewOuterFrame];
[[outerView layer] addAnimation:outerAnimation forKey:@"someKeyForMyOuterAnimation"];

[CATransaction commit];
于 2012-05-29T14:53:09.220 に答える