方向更改期间平滑的纵横比变化



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

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

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

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

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

最新更新