Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/42.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 方向更改期间平滑的纵横比更改_Iphone_Objective C_Ios_Opengl Es 2.0_Aspect Ratio - Fatal编程技术网

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

Iphone 方向更改期间平滑的纵横比更改,iphone,objective-c,ios,opengl-es-2.0,aspect-ratio,Iphone,Objective C,Ios,Opengl Es 2.0,Aspect Ratio,当iPhone的屏幕方向改变时,我会将3D渲染的投影矩阵调整为新的纵横比值。但是,在willRotateToInterfaceOrientation或didRotateFromInterfaceOrientation中执行此操作将导致过渡期间纵横比错误,因为在动画开始时,屏幕大小仍然与之前相同,并且在旋转时逐渐更改为新边界。因此,我希望用于3D投影矩阵的纵横比值也逐渐改变。为了实现这一点,我在WillAnimateRotationInterfaceOrientation中检索旋转动画的开始时间和

当iPhone的屏幕方向改变时,我会将3D渲染的投影矩阵调整为新的纵横比值。但是,在
willRotateToInterfaceOrientation
didRotateFromInterfaceOrientation
中执行此操作将导致过渡期间纵横比错误,因为在动画开始时,屏幕大小仍然与之前相同,并且在旋转时逐渐更改为新边界。因此,我希望用于3D投影矩阵的纵横比值也逐渐改变。为了实现这一点,我在
WillAnimateRotationInterfaceOrientation
中检索旋转动画的开始时间和持续时间:

- (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);
}
请注意,视图边界大小已设置为动画后有效的新值

然后,在更新中,我执行以下操作:

- (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); 
这导致在旋转过程中几乎没有可见的图像拉伸,但是如果仔细观察,图像之间的某个地方似乎仍然有点不匹配。我想,最终用户不会注意到这一点,但我想问的是,是否有更好的解决方案,以下是我的问题:

  • 在旋转更改动画期间,用于纵横比更改的实际缓和功能是什么
  • 在方向更改动画期间,是否有方法获取视图显示时的实际宽度和高度?这将允许我直接检索中间方面

在第一个项目符号上,您可以使用(可能与
KCAMediatiming函数easeineAseOut
)获取定义过渡的曲线的控制点。然后使用三次贝塞尔曲线公式


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

在第一个要点上,您可以使用(可能与
KCAMediatiming函数easeAseOut
)获取定义过渡的曲线的控制点。然后使用三次贝塞尔曲线公式


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

使用
presentationLayer
维度的解决方案看起来不错而且干净。我在
GLKViewController
update
方法中更新它,该方法作用于
CADisplayLink
。在模拟器的“慢动作”视图中,结果看起来非常完美,但是它似乎落后于设备上的至少一帧,这是可见的,如果你知道的话,但这是可以接受的。我将这样使用它,因为它很简单。使用
presentationLayer
维度的解决方案看起来很好而且干净。我在
GLKViewController
update
方法中更新它,该方法作用于
CADisplayLink
。在模拟器的“慢动作”视图中,结果看起来非常完美,但是它似乎落后于设备上的至少一帧,这是可见的,如果你知道的话,但这是可以接受的。我将这样使用它,因为它很简单。