SwiftUI 共享表使 iPad 崩溃

问题描述 投票:0回答:3

我正在关注本教程https://jeevatamil.medium.com/how-to-create-share-sheet-uiactivityviewcontroller-in-swiftui-cef64b26f073

向我的 swiftui 应用程序添加一个简单的共享表。它在 iPhone 上运行正常,但在 iPad 上崩溃并出现此错误

Terminating app due to uncaught exception 'NSGenericException', reason: 'UIPopoverPresentationController (<UIPopoverPresentationController: 0x107d95ee0>) should have a non-nil sourceView or barButtonItem set before the presentation occurs.'

有什么办法可以解决这个错误吗?不太确定这里发生了什么。谢谢!

swift swiftui swift5 uiactionsheet
3个回答
3
投票

您只需在

sourceView
sourceRect
上设置
UIActivityViewController
popoverPresentationController
即可。这是一个比我迄今为止看到的更完整和正确的示例:

// Get a scene that's showing (iPad can have many instances of the same app, some in the background)
let activeScene = UIApplication.shared.connectedScenes.first(where: { $0.activationState == .foregroundActive }) as? UIWindowScene
        
let rootViewController = (activeScene?.windows ?? []).first(where: { $0.isKeyWindow })?.rootViewController
        
// iPad stuff (fine to leave this in for all iOS devices, it will be effectively ignored when not needed)
activityVC.popoverPresentationController?.sourceView = rootViewController?.view
activityVC.popoverPresentationController?.sourceRect = .zero
        
rootViewController?.present(activityVC, animated: true, completion: nil)

0
投票

尝试使用此代码在 iPad 中打开 Actionsheet。

if let vc = UIApplication.shared.windows.first?.rootViewController{
        let activityVC = UIActivityViewController(activityItems: [urlShare], applicationActivities: nil)
        if isIpad{
            activityVC.popoverPresentationController?.sourceView = vc.view
            activityVC.popoverPresentationController?.sourceRect = .zero
        }
        UIApplication.shared.windows.first?.rootViewController?.present(activityVC, animated: true, completion: nil)
    }

0
投票

这是一个没有任何警告的解决方案,也适用于 iPad。

Button {
    let AV = UIActivityViewController(activityItems: ["Hello World!"], applicationActivities: nil)
    let activeScene = UIApplication.shared.connectedScenes.first(where: { $0.activationState == .foregroundActive }) as? UIWindowScene
    let rootViewController = (activeScene?.windows ?? []).first(where: { $0.isKeyWindow })?.rootViewController
    // for iPad. if condition is optional.
    if UIDevice.current.userInterfaceIdiom == .pad{
        AV.popoverPresentationController?.sourceView = rootViewController?.view
        AV.popoverPresentationController?.sourceRect = .zero
    }
    rootViewController?.present(AV, animated: true, completion: nil)
    
} label: {
    Image(systemName: "square.and.arrow.up")
     
}
© www.soinside.com 2019 - 2024. All rights reserved.