为什么 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)都没有这个问题。
我试过设置 sourceView
和 sourceRect
,但似乎没有帮助。
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 呈现它。这为我解决了问题(尽管这是一种一般情况下行不通的解决方法)。
我正在展示一个 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)都没有这个问题。
我试过设置 sourceView
和 sourceRect
,但似乎没有帮助。
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 呈现它。这为我解决了问题(尽管这是一种一般情况下行不通的解决方法)。