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

iOS SwiftUI在Preferences sheet的onDismiss中触发Share Sheet iPad崩溃问题

iPad端调用UIActivityViewController崩溃修复方案

崩溃原因

  • iPadOS 系统规定,以弹窗形式展示的控制器(包括UIActivityViewController)的UIPopoverPresentationController必须绑定sourceView或barButtonItem来指定弹窗的锚点位置,否则会触发你遇到的报错
  • iPhone 端分享页默认采用全屏模态弹出的交互,不需要配置锚点参数,所以运行正常

修复代码

只需要在弹出UIActivityViewController之前,针对iPad设备额外配置弹窗锚点即可,修改后代码如下:

Button("Prefs") {
    theCurrentLog.prefsAreVisible.toggle()
}
.sheet(isPresented:$theCurrentLog.prefsAreVisible, onDismiss: {
    guard let data = currentPrefs.exportURL,
          let rootVC = UIApplication.shared.windows.first?.rootViewController else { return }
    let av = UIActivityViewController(activityItems: [data], applicationActivities: nil)
    // 新增iPad适配代码,指定弹窗锚点
    if UIDevice.current.userInterfaceIdiom == .pad {
        av.popoverPresentationController?.sourceView = rootVC.view
        // 可根据需求调整弹窗在视图中的位置,这里默认居中展示
        av.popoverPresentationController?.sourceRect = CGRect(x: rootVC.view.bounds.midX, y: rootVC.view.bounds.midY, width: 0, height: 0)
        // 不设置箭头方向时默认可自适应,也可以手动指定允许的箭头方向
        av.popoverPresentationController?.permittedArrowDirections = []
    }
    rootVC.present(av, animated: true)
}) {
    Prefs(currentPrefs: $currentPrefs)
}

补充说明

如果希望分享弹窗锚定到触发Prefs页面的按钮上,可以提前存储按钮的frame作为sourceRect的值,弹窗展示位置会更符合用户直觉。

内容的提问来源于stack exchange,提问作者Ben Long

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 10:18:03