You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS应用WKWebView中Alert弹窗触发崩溃,添加代码仍未解决求助

问题描述

我开发了一款集成WKWebView的iOS应用,点击带有Alert弹窗的链接时,应用崩溃并跳转至AppDelegate,收到如下提示:

Your application has presented a UIAlertController (<UIAlertController: 0x7f916a840a00>) of style UIAlertControllerStyleActionSheet from Kronos_Sport.ViewController (<Kronos_Sport.ViewController: 0x7f9168808c00>). The modalPresentationStyle of a UIAlertController with this style is UIModalPresentationPopover. You must provide location information for this popover through the alert controller's popoverPresentationController. You must provide either a sourceView and sourceRect or a barButtonItem. If this information is not known when you present the alert controller, you may provide it in the UIPopoverPresentationControllerDelegate method -prepareForPopoverPresentation.

我不确定要在ViewController里加什么代码才能修复这个问题。

补充说明:我已经在viewDidLoad里加了下面这段代码,但应用还是崩溃:

self.popoverPresentationController?.delegate = self

self.popoverPresentationController?.sourceView = self.view
self.popoverPresentationController?.sourceRect = self.view.bounds
self.popoverPresentationController?.permittedArrowDirections = []
解决方案

你现在的问题核心是:WKWebView里JS触发的ActionSheet弹窗,不是你ViewController自身的popoverPresentationController,所以你在viewDidLoad里设置自己的popover属性根本没用。

正确的做法是通过WKUIDelegate协议拦截并处理WebView的弹窗:

  1. 先让你的ViewController遵守WKUIDelegate和UIPopoverPresentationControllerDelegate协议:
class ViewController: UIViewController, WKUIDelegate, UIPopoverPresentationControllerDelegate {
    // ... 你的其他代码
}
  1. 给WKWebView实例设置uiDelegate为当前ViewController:
webView.uiDelegate = self
  1. 实现WKUIDelegate中处理确认弹窗(对应JS的confirm)的方法,手动创建UIAlertController并配置好popover参数:
func webView(_ webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (Bool) -> Void) {
    let alertController = UIAlertController(title: nil, message: message, preferredStyle: .actionSheet)
    
    // 配置popover的位置信息,绑定到WebView上
    alertController.popoverPresentationController?.sourceView = webView
    alertController.popoverPresentationController?.sourceRect = webView.bounds
    alertController.popoverPresentationController?.permittedArrowDirections = []
    alertController.popoverPresentationController?.delegate = self
    
    // 添加按钮并处理回调
    alertController.addAction(UIAlertAction(title: "确认", style: .default) { _ in
        completionHandler(true)
    })
    alertController.addAction(UIAlertAction(title: "取消", style: .cancel) { _ in
        completionHandler(false)
    })
    
    present(alertController, animated: true)
}

// 实现代理方法,确保iPad上弹窗正常展示
func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
    return .none
}

如果还需要处理普通的Alert弹窗(对应JS的alert),也要实现对应的方法:

func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void) {
    let alertController = UIAlertController(title: nil, message: message, preferredStyle: .alert)
    alertController.addAction(UIAlertAction(title: "确定", style: .default) { _ in
        completionHandler()
    })
    present(alertController, animated: true)
}

这样就能拦截WebView中JS触发的所有弹窗,正确配置popover的位置信息,解决崩溃问题。

内容的提问来源于stack exchange,提问作者Camille Gallet

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 16:54:28