Button Tap - ShareSheet rootViewController Issue

45 Views Asked by At

I'm having issues when tapping buttons that either open the share sheet or email.

Behavior - Does not work when app is launched after install. Works fine after restarting app.

UIApplication.shared.windows.first?.rootViewController?.present(shareController, animated: true, completion: nil)

Behavior - Works fine when app is launched after install. Does not work after restarting app.

UIApplication.shared.windows.first?.rootViewController!.presentedViewController?.present(shareController, animated: true, completion: nil)

Log details:

Attempt to present which is already presenting.

ShareSheet connection invalidated.

I need this to work in both scenarios.

2

There are 2 best solutions below

0
Berhanwar On BEST ANSWER

This worked for me earlier today:

Extension:

extension UIApplication {
    
static func TopPresentedViewController() -> UIViewController? {
    
    guard let rootViewController = UIApplication.shared
            .connectedScenes.lazy
            .compactMap({ $0.activationState == .foregroundActive ? ($0 as? UIWindowScene) : nil })
            .first(where: { $0.keyWindow != nil })?
            .keyWindow?
            .rootViewController
    else {
        return nil
    }
    
    var topController = rootViewController
    
    while let presentedViewController = topController.presentedViewController {
        topController = presentedViewController
    }
    
    return topController
   } 
}

To present:

UIApplication.TopPresentedViewController?.present(activityViewController, animated: true, completion: nil) 
0
Mitul Pokiya On

Here's a way to handle it:

if let rootViewController = UIApplication.shared.windows.first?.rootViewController {
    if let presentedViewController = rootViewController.presentedViewController {
        // If there's a presented view controller, dismiss it first
        presentedViewController.dismiss(animated: false) {
            // Now, present the share controller
            rootViewController.present(shareController, animated: true, completion: nil)
        }
    } else {
        // If there's no presented view controller, present the share controller directly
        rootViewController.present(shareController, animated: true, completion: nil)
    }
}