0

iPhone の画面の向きが変わると、3D レンダリングの射影行列を新しいアスペクト値に調整します。ただし、どちらかでこれを行うwillRotateToInterfaceOrientationdidRotateFromInterfaceOrientation、アニメーションの開始時に画面サイズが以前と同じであり、回転しながら徐々に新しい境界に変更されるため、移行中に縦横比が正しくなくなります。したがって、3D プロジェクション マトリックスに使用するアスペクト値も徐々に変化させたいと考えています。これを実現するために、回転アニメーションの開始時間と継続時間を取得しますwillAnimateRotationToInterfaceOrientation

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    _aspect.isChanging = YES;
    _aspect.startedChanging = [[NSDate date] retain];
    _aspect.changeDuration = duration;
    _aspect.oldValue = self.renderer.aspect;
    _aspect.currentValue = fabsf(self.view.bounds.size.width / self.view.bounds.size.height);
}

ビューの境界サイズは、アニメーション後に有効になる新しい値に既に設定されていることに注意してください。

次に、 でupdate次のことを行います。

- (void)update
{
    if (_aspect.isChanging) {
        float f = MIN(1, [[NSDate date] timeIntervalSinceDate:_aspect.startedChanging] / _aspect.changeDuration);
        self.renderer.aspect = _aspect.oldValue * (1-f) + _aspect.currentValue * f;
    } else {
        self.renderer.aspect = _aspect.currentValue;
    }
    [self.renderer update];
}

これはすでに非常にうまく機能していますが、レンダリングのアスペクトの変更は実際のアスペクトの変更と一致しません。これは、線形に補間しているためです。したがって、問題に数学関数を投げて、実際のアスペクト変更の緩和に合わせようとしました: 私が得ることができた最良の結果は、次の行を追加することでした:

f = 0.5f - 0.5f*cosf(f*M_PI); 

これにより、回転中に画像が引き伸ばされることはほとんどありませんが、よく見ると、その間のどこかでまだ少し一致していないように見えます. エンドユーザーは気付かないだろうと思いますが、もっと良い解決策があるかどうかここで尋ねているので、これらが私の質問です:

  • 回転変化アニメーション中の縦横比の変化に使用される実際のイージング関数は何ですか?
  • 方向変更アニメーション中に表示されるビューの実際の幅と高さを取得する方法はありますか? これにより、中間の側面を直接取得できます。
4

1 に答える 1

3

最初の箇条書きでは、CAMediaTimingFunction(おそらく と一緒にkCAMediaTimingFunctionEaseInEaseOut) を使用して、遷移を定義する曲線の制御点を取得できます。次に、3 次ベジエ曲線の式を使用します。

2 番目の箇条書きでは、現在の状態に従って現在のすべてのアニメーションが適用された[[view layer] presentationLayer]、そのビューのバージョンを取得するために使用できます。CALayerしたがって、その寸法を確認すると、現在の値を取得する必要があります —CADisplayLinkコールバックに基づいて行動すると、せいぜい 1 フレーム遅れることになると思います。

于 2012-08-18T19:00:10.257 に答える