GLKViewControllerDelegate被阻塞了

8

我有一个GLKViewController来处理一些OpenGL绘图。我已经实现了glkView:drawInRectupdate方法,并将preferredFramesPerSecond属性设置为30(默认值)。

问题在于,当用户与应用程序的其他部分进行交互时,委托方法会停止触发。 我看到这种情况发生的两种情况是当用户滚动UITableView或与MKMapView交互时。

是否有一种方法可以确保这些委托始终触发,而不管应用程序的其余部分正在做什么。 我希望它们停止的唯一时间是当应用程序进入后台时(它会自动执行此操作)。


没有任何相关的代码。在GLKViewController初始化中,我将preferredFramesPerSecond设置为30。 - Ross Kimes
1个回答

15
这是因为在表视图或地图视图中滚动时,运行循环处于UITrackingRunLoopMode,该模式的优先级高于默认模式。这可以防止一些事件触发以保证高滚动性能。 为了解决您的问题,您必须设置自己的渲染循环,而不是依赖于GLKViewController
  • 首先将GLKViewenableSetNeedsDisplay设置为NO(使用GLKViewController时应自动设置)。
  • preferredFramesPerSecond设置为0(或1)以禁用GLKViewController的渲染循环,或根本不使用GLKViewController。
  • 导入QuartzCore框架:#import <QuartzCore/QuartzCore.h>
  • 创建一个CADisplayLink并将其安排在NSRunLoopCommonModes中:
CADisplayLink* displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(render:)];
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
  • 可选:将displayLink的frameInterval设置为2(等于帧率的一半)
  • render方法:
- (void)render:(CADisplayLink*)displayLink {
    GLKView* view = (GLKView*)self.view;
    [view display];
}
我没有测试过,所以如果能正常工作,请告诉我!

3
这个方法确实可行。我一直在寻找不用这么做的方式,但我认为你说的是唯一的方法。 - Ross Kimes
由于某种原因,这导致我的帧速率下降到每帧2秒! - Joseph Humfrey
@JosephHumfrey请检查CADisplayLink的frameInterval属性(默认值为1)。也许你错设置成了30?帧率应该等于 1 / (displayLink.frameInterval * displayLink.duration) - Felix

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接