GLKit的-drawRect:在屏幕旋转期间不调用

时间:2013-03-07 19:18:03

标签: ios glkit screen-rotation auto-rotation glkview

我有基于GLKit的应用,并显示了一些简单的对象。

一切正常,除了屏幕旋转,在此期间GLKView未更新(-drawRect:未被调用)。因此,在旋转期间,投影矩阵不会根据动态变化的屏幕大小进行更新,并且对象看起来很糟糕(拉伸)。

3 个答案:

答案 0 :(得分:6)

由于我没有使用GLKit的任何经验,这可能是在黑暗中拍摄的,但我确实有使用UIView-drawRect:的经验。尝试更改相关视图的contentMode以重绘:

view.contentMode = UIViewContentModeRedraw;

这将告诉视图,当边界发生变化时,需要重绘它的内容。否则,UIView将只是尝试缩放其内容(contentMode的默认值为UIViewContentModeScaleToFill)。这样做的原因是,缩放内容比重绘内容要容易得多,UIView的设计尽可能高效。

答案 1 :(得分:1)

这根本不是UIKit动画的工作方式。我在this answer中解释了它的一半是如何工作的,但我会尝试总结相关的部分:

  • 一切都是带纹理的矩形。 (有一些例外,比如CAShapeLayer,但大多数情况都是如此。)
  • UIView的属性链接到CALayer的“模型树”属性。他们即时更改
  • 动画的工作原理是将“演示树”属性从起始值设置为当前模型值。
  • 默认情况下,动画的起始值是先前的模型值。指定UIViewAnimationOptionBeginFromCurrentState会使其使用当前的演示文稿值。

当然,有一些例外(CAShapeLayer似乎不仅仅是纹理矩形,UIScrollView在定时器上滚动动画,UIView转换完全是另一回事......)。

假设的轮换是如何工作的,你得到一个-setFrame:,一切都被布局(并且可能被重新渲染),然后动画属性被动画化。默认情况下,这意味着事物会重新渲染到新的尺寸,但会拉伸以适应旧的尺寸,然后随着旋转的进行动画(和不拉伸)。

尽管如此,GLKView可能会有所不同。如果您正在使用GLKViewController,它甚至可能会在旋转动画期间暂停渲染。您可以尝试在轮换期间调用-setNeedsDisplay,但由于帧已设置为其最终值,因此无效。

自己处理旋转动画的最简单方法可能是将非动画重新布局强制转换为旋转帧,然后在渲染器中进行一些捏造(黑色边框和状态栏分别进行动画处理)。

或者,传统的方法是让你的VC仅限肖像并自己处理设备方向通知,但这是一大堆蠕虫(你必须担心状态栏方向,这决定了触摸偏移等事情和键盘方向,当转换到/从其他VC转换时,它倾向于“有趣地”交互。

答案 2 :(得分:0)

首先,确保在应用程序生命周期的早期阶段,启用设备方向更改。

[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];

然后,当您的视图被实例化时,请注册这样的通知。

[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(deviceOrientationDidChange:) name: UIDeviceOrientationDidChangeNotification object: nil];

然后在视图控制器中实施-deviceOrientationDidChange:并致电-setNeedsDisplay