7

I was following this tutorial https://jeevatamil.medium.com/how-to-create-share-sheet-uiactivityviewcontroller-in-swiftui-cef64b26f073

to add a simple share sheet to my swiftui app. It works properly on iPhones but crashes on iPad with this error

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

Any way to get around this error? Not exactly sure what's happening here. Thanks!

Boeggles
  • 59
  • 1
  • 6
  • Welcome to SO. Rather than posting links to code (which can go stale), it's generally a better idea to include a [mre] here in code. Taking a glance at that tutorial, you could try to set `sourceView` to the root view controller's view, for example, but you make find better luck using `UIViewControllerRepresentable` : https://stackoverflow.com/a/58341956/560942 – jnpdx Apr 13 '21 at 16:26

2 Answers2

2

You just need to set sourceView and sourceRect on the UIActivityViewController's popoverPresentationController. Here's a more complete and correct example than I've seen so far:

// 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)
Trev14
  • 3,626
  • 2
  • 31
  • 40
0

Try this code to open Actionsheet in iPad.

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)
    }
Dhaval Bera
  • 109
  • 4