为什么 UIActivityViewController 在演示者上调用 viewWillDisappear()?

Why does UIActivityViewController call viewWillDisappear() on the presenter?

我正在展示一个 UIActivityViewController 来分享来自 URL:

的 .mp4 视频
let viewController: UIViewController = ... // the presenting view controller
let url: URL = ... // local file

let activityController = UIActivityViewController(activityItems: [url], applicationActivities: nil)
viewController.present(activityController, animated: false, completion: nil)

When the "save video" option is selected, the video is saved, but the presenting UIViewController disappears (and I can see that .viewWillDisappear() is called on it.)

如何让呈现 UIViewController 不消失?

请注意,我尝试过的所有其他共享选项(消息、空投、instagram)都没有这个问题。

我试过设置 sourceViewsourceRect,但似乎没有帮助。

activityController.popoverPresentationController?.sourceView = viewController.view!
activityController.popoverPresentationController?.sourceRect = viewController.view!.frame

我查找了错误,但没有找到:

activityController.completionWithItemsHandler = { (a: UIActivity.ActivityType?, b: Bool, c: [Any]?, d: Error?) in
    if let error = d {
        print(error)
    }
}

此外,我所有的 UIViewController 生命周期覆盖都调用它们的超级,即:

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
}

这是它的样子:

它让我的整个视野​​都崩塌了!

对于它的价值,viewController 是通过调用在故事板中设置的 segue 来设置的:

class LaunchController : UIViewController {

    var performedSegue = false

    override func viewDidLayoutSubviews() {
        if !performedSegue {
            self.performSegue(withIdentifier: "main", sender: self)
            performedSegue = true
        }
    }
}

这个"feature"貌似是Apple在iOS13推出的,我测试过 这在 iOS 12 和呈现 ViewController 不会消失。

我跟踪了调用堆栈,当成功保存到相机胶卷时,UIActivityViewController 似乎在呈现视图控制器(或其 UINavigationController)上调用关闭。

我不知道如何防止这种情况发生,因为它是 Apple 私有的 API,并且文档中没有关于此的任何内容。我发现的唯一方法是设置某种标志 savingToCameraRoll 并在呈现 UIActivityViewController 时将其设置为 true,在呈现 [=33= 时覆盖 dismiss 方法] 然后在 dismiss.

中检查这个标志
override func dismiss(animated flag: Bool, completion: (() -> Void)? = nil) {
    if !savingToCameraRoll {
         // Dismiss view controller if UIActivityViewController not in use
         super.dismiss(animated: animated, completion: completion)
    }

    // Handle UIActivityViewController dismiss attempt. 
    // If you do nothing, the presenting ViewController should not be dismissed.
}

你还应该记得在completionWithItemsHandler中将savingToCameraRoll设置为false

在情节提要中,我将呈现 ViewController 标记为 "Is Initial View Controller",而不是通过 segue 呈现它。这为我解决了问题(尽管这是一种一般情况下行不通的解决方法)。