0

There is a share button in my application in a view controller of product details page. By pressing share button, an API called then after response, i am model presenting UIActivityViewController to share the URLs and other things. The problem is that in some stage api getting time to fetch share data, in that mean time user can move back to previous view controller or move forward to another view controller.

My question is how can I stop presenting UIActivityViewController if i am not in that screen when its going to present? I may be on next screen in navigation or move back.

Another issue I am facing if UIActivityViewController get present on another screen with respect to above case, then dismissing that making my whole app interaction disabled in iOS 13 because an UIDimming type view appears in main UIWindow which is not getting dismiss when dismissing UIActivityViewController.

Here is the code:

@IBAction private func toolbarShareStonesBtnPressed(_ sender: UIBarButtonItem) {
    guard !isSharingInProgress else { return }
    Utils.showLoading(forTargetVC: self)
    isSharingInProgress = true
    viewModel.getSelectedStonesShareLinks { [weak self] (errorMsg, shareURLs) in
        guard let `self` = self else { return }
        Utils.hideLoading(forTargetVC: self)
        self.isSharingInProgress = false
        if let errorMsg = errorMsg {
            Utils.showAlert(withMessage: errorMsg)
        } else if let shareURLs = shareURLs {
            let activityViewController = UIActivityViewController(activityItems: shareURLs , applicationActivities: nil)
            activityViewController.popoverPresentationController?.sourceView = self.view
            if let popoverController = activityViewController.popoverPresentationController {
                popoverController.barButtonItem = sender
                popoverController.permittedArrowDirections = .any
            }
            self.present(activityViewController, animated: true, completion: nil)
        }
    }
}
Gurjit Singh
  • 1,723
  • 21
  • 27
  • Show your code? – matt Dec 10 '19 at 06:42
  • @matt I have updated above. – Gurjit Singh Dec 10 '19 at 06:45
  • why not disable the user interaction till the activityViewController is presented ? You can show an activity indicator. – Keshu R. Dec 10 '19 at 06:49
  • @KeshuRai I don't want to make user wait, if api getting time then user can move to other stuffs rather than stuck. user can also swipe back or can access items in navigation bar. – Gurjit Singh Dec 10 '19 at 06:54
  • 1
    you can use this answer to check if the current view controller is topViewController or not -> https://stackoverflow.com/a/39857342/8374890 . If it is topViewController, present the activityViewController else not . – Keshu R. Dec 10 '19 at 07:17

1 Answers1

2

I’d say you are doing this backward. When the button is tapped, present the activity view controller immediately. For your activity item, use a UIActivityItemProvider.

https://developer.apple.com/documentation/uikit/uiactivityitemprovider

That is its whole purpose, to act as a conduit when your activity item needs some time to fetch the data. It is an Operation so now you can network asynchronously in the background. Meanwhile the activity view is up, and prevents navigation unless the user gives up and cancels it.

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • thanks for answer. Can you explain more with example if possible that how can in change UIActivityViewController actions later after its present and api call finish? – Gurjit Singh Dec 10 '19 at 07:24
  • Really Helpful Answer. I have created my custom UIActivityItemProvide which returns me sharing urls with the help of: https://www.whitesmith.co/blog/control-what-youre-sharing/. – Gurjit Singh Dec 10 '19 at 08:23