iOS 13 UIActivityViewController automatically present previous VC after image saving

I'm trying to implement “Save image to Library” function and then return back to the current view controller, but on a new iOS 13 it dismisses back to the view controller that presented the current one:


PHPhotoLibrary.requestAuthorization({(_ status: PHAuthorizationStatus) -> Void in })

let shareItems: Array = [newImg,"Hello"] as [Any]

let activityController = UIActivityViewController(activityItems: shareItems, applicationActivities: nil)

if UIDevice.current.userInterfaceIdiom == .pad {
  activityController.popoverPresentationController?.sourceView = saveButton
}

present(activityController, animated: true)

Replies

I see this as well. Very frustrating... Unfortunately, no solution yet.

This is affecting us too and causing a crash in our app since our app is not expecting this behavior.

Same here. Other share actions seem to leave the presenting view controller in place - only the Save Image function leads to dismissal. Testing on iOS 11.2 and iOS12.0 shows it doesn't happen there. Must surely be an OS bug introduced in iOS13. Couldn't find any way to trap it or prevent it in my own code. Unfortunately I have users who are annoyed by this behaviour as it interrupts their workflow with the app. Would love a workaround if anyone can find one.

I don't know if this will help or not, but I found what was causing the issue for me: I copied a button on the main View Controller to repurpose it to open the secondary View Controller with the UIActivityViewController. The button I copied was originally for closing the main View Controller. When I copied the button, Xcode didn't remove the message to the code to close the View Controller. In order to view the secondary View Controller, I used a direct segue (control drag to the new View controller). So, when I pressed the button to view the View Controller with the UIActivityViewController, the direct segue fired and showed the secondary View Controller long enough for the button to then call the close code on the first View Controller, which somehow made the second View Controller close.


After I removed the incorrect action in the button, I was able to see the UIActivityViewController without any issues. (Well, there was one issue: I needed to set popoverPresentationController?.canOverlapSourceViewRect to true.)


I hope this helps!


Stuart

I think this must have been a seaparate issue particular to your code. To know for sure, can you test whether or not, when you choose "Save Image" option from the share sheet (using iOS 13) your view controller gets dismissed at same time as share sheet is dismissed, immediately after save, whereas your own view controller doesn't get dimissed (i.e. just share sheet gets dismissed, as expected) when you choose any other share option?

I strongly suspect you are right that this was different that what others have reported but wanted to let people know what I found just in case. In my case, the second view controller disappeared after appearing for less than a second - I was unable to invoke the UIActivityViewController (which should have been a hint to me) to press the save button.

Not sure if this helps anyone, but we're getting the same issue with 'Save Video'.


Seems not to be an issue if different share actions are used.

For us it's only happening on 'Save Video'.


'Save to to Files' or 'Save to Dropbox' do not trigger this issue for us.
Looking for a solution.

Same issue here on latest iOS 13.3.1

This is very annoying: anybody found a workourond? I was thinking of having a transparent UIViewController wrapping the share sheet

If it helps anyone, found this workaround in SO.


let fakeViewController = TransparentViewController()
fakeViewController.modalPresentationStyle = .overFullScreen

activityViewController.completionWithItemsHandler = { [weak fakeViewController] _, _, _, _ in
  if let presentingViewController = fakeViewController?.presentingViewController {
  presentingViewController.dismiss(animated: false, completion: nil)
  } else {
  fakeViewController?.dismiss(animated: false, completion: nil)
  }
}
present(fakeViewController, animated: true) { [weak fakeViewController] in
  fakeViewController?.present(activityViewController, animated: true, completion: nil)
}


Tested in iOS 13.3.1 and works as expected.

Same here. I was going crazy thinking I'm doing something wrong.

Hi! This solution save my time!
https://stackoverflow.com/a/61032571/5648975

Has anyone figured out a fix for this issue? It still happens for me as of iOS 13.5.1
(I've created a project which reproduces the issue here)
The issue is also happening on latest iOS 14 beta 5.

the below workaround solution works for me, presenting a invisible view controller first and then presenting activity vc.
so, it activity vc won't harm required vc, invisible vc will get dismissed instead.

Code Block
let vc = UIViewController()
vc.modalPresentationStyle = .overCurrentContext
vc.view.backgroundColor = .clear
avc.completionWithItemsHandler = { [weak vc] (_, _, _, _) in
if let pvc = vc?.presentingViewController {
pvc.dismiss(animated: true, completion: nil)
} else {
vc?.dismiss(animated: false, completion: nil)
}
}
present(vc, animated: false) { [weak vc] in vc?.present(avc, animated: true) }




Seeing this in iOS 15, too.

  • Having same Issue in iOS 15.4.1:

    UIActivityViewController when save image is tapped it will save image as well as close the modal with parent view controller.

    Solution:

    User custom ActivityViewController:

    class CustonActivityViewController: UIActivityViewController { override func dismiss(animated flag: Bool, completion: (() -> Void)? = nil) { // super.dismiss(animated: true, completion: completion) // Disabling this above dismiss will not close your parent view controller. } }

Add a Comment