0

当 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); 

这导致在旋转过程中几乎看不到图像的拉伸,但是如果你仔细观察,在两者之间的某个地方似乎仍然有点不匹配。我想,最终用户不会注意到它,但我在这里问是否有更好的解决方案,所以这些是我的问题:

  • 旋转变化动画期间用于纵横比变化的实际缓动函数是什么?
  • 有没有办法在方向更改动画期间获取视图的实际宽度和高度?这将允许我直接检索中间方面。
4

1 回答 1

3

在第一个要点上,您可以使用CAMediaTimingFunction(可能使用kCAMediaTimingFunctionEaseInEaseOut)来获取定义过渡的曲线的控制点。然后只需使用三次贝塞尔曲线公式。

在第二个要点上,您可以使用[[view layer] presentationLayer]获取该视图的版本,CALayer其中所有当前动画都根据其当前状态应用。所以如果你检查它的尺寸,你应该得到当时的值——我猜如果你对CADisplayLink回调采取行动,那么你最多会落后一帧。

于 2012-08-18T19:00:10.257 回答