Search code examples
macosswiftuiwkwebview

How to modify File open panel


I am building an application that displays a WebView using SwiftUI. I was able to get as far as displaying the content, but when I click on upload files, the file selection panel appears, but the panel is displayed in the center of the screen, not in the center of the WebView like Safari. How can I make the panel appear in the center of the window like in Safari?

For reference, UIDelegate's runOpenPanelWith method is written as follows

public func webView(_ webView: WKWebView, runOpenPanelWith parameters: WKOpenPanelParameters, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping ([URL]?) -> Void) {
    let openPanel = NSOpenPanel()
    openPanel.prompt = String(localized: "Upload")
    openPanel.message = String(localized: "title")
    openPanel.canChooseFiles = true
    openPanel.begin { (result) in
        if result == NSApplication.ModalResponse.OK {
            if let url = openPanel.url {
                completionHandler([url])
            }
        } else if result == NSApplication.ModalResponse.cancel {
            completionHandler(nil)
        }
    }
}

Solution

  • Use beginSheetModal to present the open panel. You can get the NSWindow needed for this by webView.window.

    func handleResult(_ result: NSApplication.ModalResponse) {
        if result == NSApplication.ModalResponse.OK, let url = openPanel.url {
            completionHandler([url])
        } else {
            completionHandler(nil)
        }
    }
    if let window = webView.window {
        openPanel.beginSheetModal(for: window, completionHandler: handleResult)
    } else { // web view is somehow not in a window? Fall back to begin
        openPanel.begin(completionHandler: handleResult)
    }