Tee*_*ppa 9 iphone animation event-handling event-loop uikit
有没有人知道或有很好的链接解释iPhone的事件循环在幕后做什么?
我们在基于OpenGL的iPhone游戏框架中使用自定义事件循环.它调用我们的游戏渲染系统,使用CFRunLoopRunInMode调用presentRenderbuffer和泵事件.有关详细信息,请参阅以下代码
当我们不使用UIKit控件(作为证明,尝试Facetap,我们的第一个发布的游戏)时,它运行良好.
但是,使用UIKit的控件时,一切都差不多的作品,但并不完全.具体来说,滚动UIKit控件无法正常工作.
例如,让我们考虑以下场景.
如上所述,一切都有效,滚动除外.
问题:滚动时,抬起手指后立即停止滚动.通常情况下,它会根据您的移动速度顺利进行,但不会在我们使用自定义事件循环时继续.似乎iPhone的事件循环正在做一些与我们自己没有实现的UIKit滚动相关的魔术.
现在,我们可以通过使用Apple的事件循环并通过NSTimer回调调用我们自己的渲染,让UIKit控件与我们自己的系统一起工作得很好.但是,我仍然想了解,在我们的自定义事件循环中未实现的iPhone事件循环中可能发生的事情.
- (void)customEventLoop { OBJC_METHOD;
float excess = 0.0f;
while(isRunning) {
animationInterval = 1.0f / openGLapp->ticks_per_second();
// Calculate the target time to be used in this run of loop
float wait = max(0.0, animationInterval - excess);
Systemtime target = Systemtime::now().after_seconds(wait);
Scope("event loop");
NSAutoreleasePool* pool = [[ NSAutoreleasePool alloc] init];
// Call our own render system and present render buffer
[self drawView];
// Pump system events
[self handleSystemEvents:target];
[pool release];
excess = target.seconds_to_now();
}
}
- (void)drawView { OBJC_METHOD;
// call our own custom rendering
bool bind = openGLapp->app_render();
// bind the buffer to be THE renderbuffer and present its contents
if (bind) {
opengl::bind_renderbuffer(renderbuffer);
[context presentRenderbuffer:GL_RENDERBUFFER_OES];
}
}
- (void) handleSystemEvents:(Systemtime)target { OBJC_METHOD;
SInt32 reason = 0;
double time_left = target.seconds_since_now();
if (time_left <= 0.0) {
while((reason = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, TRUE)) == kCFRunLoopRunHandledSource) {}
} else {
float dt = time_left;
while((reason = CFRunLoopRunInMode(kCFRunLoopDefaultMode, dt, FALSE)) == kCFRunLoopRunHandledSource) {
double time_left = target.seconds_since_now();
if (time_left <= 0.0) break;
dt = (float) time_left;
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果你NSLog [[NSRunLoop currentRunLoop] currentMode]从[UIScrollView setContentOffset:]什么时候开始[UIScrollView isDecelerating]是真的你就会看到UITrackingRunLoopMode。
一般来说,除了kCFRunLoopDefaultMode主 UI 线程运行循环之外,系统还会使用其他模式,仅记录了其中的一些模式。获得完整系统行为的唯一方法是与主线程上的系统运行循环配合。
您可以尝试使用NSTimer并让系统呼叫您而不是呼叫CFRunLoopRunInMode您自己。AnNSTimer可以随着时间的推移自由运行,并且当没有显示其他 UI 时,系统运行循环除了调用计时器之外不会执行任何操作。
另一种方法是在显示系统控件时从 customEventLoop 函数返回,并在恢复自定义 UI 时再次调用它。
| 归档时间: |
|
| 查看次数: |
1786 次 |
| 最近记录: |