2010-11-12 118 views
3

如何使用WebKit的WebView和模态对话框?在模态NSWindow中使用WebView无法正常工作?

[_webView setMainFrameURL:[NSString fromStdString:url]]; 
[_nsWindow makeKeyAndOrderFront:nil]; 
return [NSApp runModalForWindow:_nsWindow]; 

上述代码仅适用于Mac OS 10.6。使用10.5这不是导航到指定的URL。没有runModalForWindow,一切正常。

回答

8

WebView只适用于主循环,因此在这种情况下不合作。一种解决方案是自己运行模态会话并手动保持主循环(类似于建议的here)。例如: -

NSModalSession session = [NSApp beginModalSessionForWindow:yourWindow]; 
int result = NSRunContinuesResponse; 

// Loop until some result other than continues: 
while (result == NSRunContinuesResponse) 
{ 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

    // Run the window modally until there are no events to process: 
    result = [NSApp runModalSession:session]; 

    // Give the main loop some time: 
    [[NSRunLoop currentRunLoop] limitDateForMode:NSDefaultRunLoopMode]; 

    // Drain pool to avoid memory getting clogged: 
    [pool drain]; 
} 

[NSApp endModalSession:session]; 

请注意,你可能想使用类似-runMode:beforeDate:而不是让CPU负载下降。

+0

此网站是否有2小时前?说真的,我不知道我怎么会错过这个。非常感谢! – Dodo 2010-11-12 15:13:09

+0

@Dodo:对我来说更容易(重新)发现我猜 - 我已经经历了这个问题的更多人为的版本:) – 2010-11-12 15:30:53

1

我一直在寻找解决方案,现在我可以使用以下代码在模态会话上使用WebView。如果不使用-runMode:beforeDate我的WebView无法处理的键盘或安装事件:

- (void) OpenURL:(const char *)_url 
{ 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

    [NSApplication sharedApplication]; 
    [NSApp setDelegate:self]; 

    NSString *url = [NSString stringWithUTF8String:_url]; 

    NSLog(@"OpenURL: %@", url); 

    NSRect windowRect = NSMakeRect(10.0f, 10.0f, 800.0f, 600.0f); 

    NSWindow *window = [[NSWindow alloc] initWithContentRect:windowRect 
     styleMask:(NSResizableWindowMask|NSClosableWindowMask|NSTitledWindowMask) 
     backing:NSBackingStoreBuffered defer:NO]; 
    [window setDelegate:self]; 

    WebView *webview = [[WebView alloc] initWithFrame:windowRect 
     frameName:@"mainFrame" 
     groupName:nil]; 
    [webview setFrameLoadDelegate:self]; 
    [[webview mainFrame] 
      loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:url]]]; 

    [window setContentView:webview]; 
    [window makeKeyAndOrderFront:nil]; 

    // Modal Session 

    NSModalSession session = [NSApp beginModalSessionForWindow:window]; 
    _result = NSModalResponseContinue; 

    while (_result == NSModalResponseContinue) { 
     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

     _result = [NSApp runModalSession:session]; 

     // The event loop is a runloop data source, so any ui event will 
     // wake up the source and make this method returns, and so 
     // you can block the run loop and tell him to wait that 
     // something append. [2] 
     [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode 
            beforeDate:[NSDate distantFuture]]; 

     [self doSomeWork]; 

     [pool drain]; 
    } 
    [NSApp endModalSession:session]; 

    [pool release]; 
} 

你需要调用[NSApp stopModal][NSApp abortModal][NSApp stopModalWithCode:yourReturnCode]的地方是这样的:

- (void)windowWillClose:(NSNotification *)notification 
{ 
    NSLog(@"windowWillClose"); 
    [NSApp stopModal]; 
} 

链接: