为啥 UIActivityViewController 会在 Presenter 上调用 viewWillDisappear()?

Posted

技术标签:

【中文标题】为啥 UIActivityViewController 会在 Presenter 上调用 viewWillDisappear()?【英文标题】:Why does UIActivityViewController call viewWillDisappear() on the presenter?为什么 UIActivityViewController 会在 Presenter 上调用 viewWillDisappear()? 【发布时间】:2019-10-18 17:19:56 【问题描述】:

我正在展示一个 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)

选择“保存视频”选项时,保存视频,但介绍UIViewController消失(我可以看到.viewWillDisappear() in conte。)

如何让演示中的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
        
    

【问题讨论】:

我尝试使用单个 ViewController 制作一个简单的示例,但无法重现该问题,视频已成功保存,并且未调用 ViewWillDisappear 方法。你是如何展示你的模态视图控制器的?单视图控制器项目也会出现同样的错误吗? 哇哦,真快!很好的测试。在问题末尾添加了更多信息。 是的,我现在可以重现,这仅在您以模态方式呈现 ViewController 时发生。奇怪的问题。 尝试在你的activityController上设置modalPresentationStyle 【参考方案1】:

看起来这个“功能”是苹果在 ios 13 中引入的。我测试了 这在 iOS 12 上并且呈现的 ViewController 不会消失。

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

我不知道如何防止这种情况发生,因为它是 Apple 私有 API,并且文档中没有关于此的任何内容。我发现的唯一方法是在呈现 UIActivityViewController 时设置某种标志 savingToCameraRoll 并将其设置为 true,在呈现 ViewController 时覆盖 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

【讨论】:

【参考方案2】:

在故事板中,我将呈现的 ViewController 标记为“是初始视图控制器”,而不是通过 segue 呈现它。这为我解决了这个问题(尽管它是一种一般情况下不起作用的解决方法)。

【讨论】:

以上是关于为啥 UIActivityViewController 会在 Presenter 上调用 viewWillDisappear()?的主要内容,如果未能解决你的问题,请参考以下文章

你应该同步运行方法吗?为啥或者为啥不?

为啥使用 glTranslatef?为啥不直接更改渲染坐标?

为啥 DataGridView 上的 DoubleBuffered 属性默认为 false,为啥它受到保护?

为啥需要softmax函数?为啥不简单归一化?

为啥 g++ 需要 libstdc++.a?为啥不是默认值?

为啥或为啥不在 C++ 中使用 memset? [关闭]