如何在macOS WebView应用中用NSAlert实现JS弹窗(Alert/Confirm/Prompt)
macOS 下用 NSAlert 实现 WKWebView JS 弹窗(Alert/Confirm/Prompt)
直接替换iOS端UIAlertController的实现逻辑,对应WKUIDelegate的三个核心方法,以下是适配macOS的完整代码:
1. JS Alert 弹窗实现
对应 webView(_:runJavaScriptAlertPanelWithMessage:initiatedByFrame:completionHandler:) 方法:
func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void) { let alert = NSAlert() alert.messageText = message alert.addButton(withTitle: "确定") // macOS要求主线程弹窗,避免线程异常 DispatchQueue.main.async { alert.runModal() completionHandler() } }
2. JS Confirm 弹窗实现
对应 webView(_:runJavaScriptConfirmPanelWithMessage:initiatedByFrame:completionHandler:) 方法:
func webView(_ webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (Bool) -> Void) { let alert = NSAlert() alert.messageText = message alert.addButton(withTitle: "确定") alert.addButton(withTitle: "取消") DispatchQueue.main.async { let result = alert.runModal() // 第一个添加的按钮对应alertFirstButtonReturn,第二个对应alertSecondButtonReturn completionHandler(result == .alertFirstButtonReturn) } }
3. JS Prompt 弹窗实现
对应 webView(_:runJavaScriptTextInputPanelWithPrompt:defaultText:initiatedByFrame:completionHandler:) 方法,这部分是和iOS差异最大的地方:
func webView(_ webView: WKWebView, runJavaScriptTextInputPanelWithPrompt prompt: String, defaultText: String?, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (String?) -> Void) { let alert = NSAlert() alert.messageText = prompt alert.addButton(withTitle: "确定") alert.addButton(withTitle: "取消") // 手动创建输入框并绑定到alert的accessoryView let inputField = NSTextField(frame: NSRect(x: 0, y: 0, width: 300, height: 24)) inputField.stringValue = defaultText ?? "" alert.accessoryView = inputField DispatchQueue.main.async { let result = alert.runModal() completionHandler(result == .alertFirstButtonReturn ? inputField.stringValue : nil) } }
常见问题修正点
- 必须在主线程调用
runModal():macOS的NSAlert强制要求主线程展示,否则会出现弹窗无响应或崩溃,务必用DispatchQueue.main.async包裹弹窗逻辑。 - 按钮返回值判断:NSAlert的按钮添加顺序决定返回值,第一个按钮对应
.alertFirstButtonReturn,第二个对应.alertSecondButtonReturn,别搞混顺序。 - Prompt输入框适配:macOS没有
addTextField()方法,必须手动创建NSTextField并赋值给accessoryView,同时要设置合理的宽高保证显示正常。
内容的提问来源于stack exchange,提问作者user21955191
相关产品推荐
相关产品推荐

