2010-11-12 53 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]; 
} 

鏈接: