iPhone の画面の向きが変わると、3D レンダリングの射影行列を新しいアスペクト値に調整します。ただし、どちらかでこれを行うwillRotateToInterfaceOrientation
とdidRotateFromInterfaceOrientation
、アニメーションの開始時に画面サイズが以前と同じであり、回転しながら徐々に新しい境界に変更されるため、移行中に縦横比が正しくなくなります。したがって、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);
これにより、回転中に画像が引き伸ばされることはほとんどありませんが、よく見ると、その間のどこかでまだ少し一致していないように見えます. エンドユーザーは気付かないだろうと思いますが、もっと良い解決策があるかどうかここで尋ねているので、これらが私の質問です:
- 回転変化アニメーション中の縦横比の変化に使用される実際のイージング関数は何ですか?
- 方向変更アニメーション中に表示されるビューの実際の幅と高さを取得する方法はありますか? これにより、中間の側面を直接取得できます。