UIDocumentPickerViewController 会关闭父视图控制器



我在视图控制器中有一个WKWebView。当用户单击"上传文件"按钮(位于显示的网页上)时,会弹出UIDocumentPickerViewController。这是意料之中的,也是完全必要的,但是:

每当用户单击任何按钮("上传照片或视频"、"取消")时,UIDocumentPickerViewController都会自行关闭,并关闭它所在的父视图控制器。

我为[UIViewController dismissViewControllerAnimated:completion:]添加了一个符号断点,确实看到-dismissViewController...被调用了两次。第一次后它UIDocumentPickerViewController,在第二次之后 – 我的父视图控制器。

顺便说一句,在iPad上没有问题,可能是因为UIDocumentPickerViewController显示为弹出框。

为什么会发生这种情况,我该怎么办?

谢谢!

好的,我想我已经找到了解决这个问题的方法。WebKit 是开源的,您可以看到违规类是WKFileUploadPanel,特别是_dismissDisplayAnimated:方法被调用得过于激进,无意中触发了视图控制器的关闭。为了避免这种情况,您需要阻止对来自WKFileUploadPanel-dismissViewControllerAnimated:completion:的调用,您可以通过查找堆栈来做到这一点。下面是解决此问题的实现。

上面提到的解决方案不起作用,因为它依赖于查看特定类的调用堆栈符号,该符号在实际设备上运行时被混淆。这是我为解决此问题而采取的不同方法:

  1. weakUIDocumentMenuViewController属性添加到模式视图控制器类。
  2. 重写模态类中的-presentViewController:animated:completion:以检查并查看所呈现的视图控制器是否为UIDocumentMenuViewController,如果是,请将其设置为步骤 1 中弱属性的值。
  3. 覆盖-dismissViewControllerAnimated:completion:以检查您的弱属性是否nil,如果它尚未nil并且您的模态presentedViewControllernil,则意味着 WebKit 正在尝试在不应该关闭您的模态时关闭您的模态。在这种情况下,您可以避免调用super,否则可以继续调用它。

您也可以WKFileUploadPanel_dismissDisplayAnimated:方法滑动,以更加小心自己的视图控制器,但这会带来很大的风险。

我遇到了同样的问题,终于设法找到了解决方法。

在我的视图控制器中,如果未点击保存按钮,我会覆盖dismiss删除托管对象的方法,并且与UIImagePickerController完美配合。

由于我的应用程序使用UIDocumentPickerViewController,每次调用documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentAt url: URL)时都会删除我的托管对象,因为这会导致presentingViewController.dismiss

所以我的解决方案是从presentingViewController检查presentedViewController是否nil,不知道dismiss方法是否被UIDocumentPickerViewController调用。

所以这是我从视图控制器中覆盖的dismiss方法。

override func dismiss(animated flag: Bool, completion: (() -> Void)? = nil) {
if self.presentedViewController == nil {
// dismissed by the user
myDocument.delete()
} else {
// dismissed by the UIDocumentPickerViewController
// do nothing
}
super.dismiss(animated: flag, completion: completion)
}

希望对您有所帮助。

我也遇到了同样的问题,这发生在使用文档选择器时,发生在11.4以下的iOS版本中。在使用文档选取器的位置使用以下代码。根据我从不同论坛上读到的内容,文档选择器存在问题,并且已在更高版本的iOS中修复。

声明文档选取器的弱属性。

@property (weak, nonatomic) UIDocumentPickerViewController *_Nullable docPicker;

然后实现视图控制器委托方法:

- (void)presentViewController:(UIViewController *)viewControllerToPresent animated: (BOOL)flag completion:(void (^ __nullable)(void))completion
{
if ([viewControllerToPresent isKindOfClass:[UIDocumentPickerViewController class]])
{
_docPicker = (UIDocumentPickerViewController*)viewControllerToPresent;
}
[super presentViewController:viewControllerToPresent animated:flag completion:completion];
}
- (void)dismissViewControllerAnimated:(BOOL)flag
completion:(void (^)(void))completion
{
if (_docPicker != nil && self.presentedViewController == nil)
{
}
else
{
[super dismissViewControllerAnimated:flag completion:completion];
}
}

试试这个(工作):

navigationController?.dismiss(animated: true, completion: nil)

相关内容

  • 没有找到相关文章

最新更新