3

我有WKWebView一个视图控制器。当用户单击“上传文件”按钮(在所示网页上)时,会UIDocumentPickerViewController弹出。这是预期的,也是完全必要的,但是:

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

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

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

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

谢谢!

4

4 回答 4

2

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

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

  1. weak UIDocumentMenuViewController向您的模态视图控制器类添加一个属性。
  2. 在您的模态类中覆盖-presentViewController:animated:completion:以检查并查看正在呈现的视图控制器是否是 a UIDocumentMenuViewController,如果是,请将其设置为步骤 1 中的 weak 属性的值。
  3. 重写-dismissViewControllerAnimated:completion:以检查您的弱属性是否nil还存在,如果还没有nil,并且您的模态presentedViewController是,nil那么这意味着 WebKit 试图在不应该的情况下关闭您的模态。您可以避免super在这种情况下调用,否则继续调用它。

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

于 2017-01-04T19:25:34.083 回答
2

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

在我的视图控制器dismiss中,如果没有点击保存按钮,我会覆盖删除托管对象的方法,并且与UIImagePickerController.

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

所以我的解决方案是检查presentingViewController是否presentedViewControllernil或不知道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)
}

希望它可以帮助你。

于 2017-08-04T11:19:48.747 回答
1

我遇到了同样的问题,这发生在使用文档选择器时,并且发生在低于 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];
    }
}
于 2019-06-10T12:30:46.707 回答
0

试试这个(工作):

navigationController?.dismiss(animated: true, completion: nil)
于 2018-03-21T20:53:32.843 回答