我在视图控制器中有一个WKWebView
。当用户单击"上传文件"按钮(位于显示的网页上)时,会弹出UIDocumentPickerViewController
。这是意料之中的,也是完全必要的,但是:
每当用户单击任何按钮("上传照片或视频"、"取消")时,UIDocumentPickerViewController
都会自行关闭,并关闭它所在的父视图控制器。
我为[UIViewController dismissViewControllerAnimated:completion:]
添加了一个符号断点,确实看到-dismissViewController...
被调用了两次。第一次后它UIDocumentPickerViewController
,在第二次之后 – 我的父视图控制器。
顺便说一句,在iPad上没有问题,可能是因为UIDocumentPickerViewController
显示为弹出框。
为什么会发生这种情况,我该怎么办?
谢谢!
好的,我想我已经找到了解决这个问题的方法。WebKit 是开源的,您可以看到违规类是
WKFileUploadPanel
,特别是_dismissDisplayAnimated:
方法被调用得过于激进,无意中触发了视图控制器的关闭。为了避免这种情况,您需要阻止对来自WKFileUploadPanel
的-dismissViewControllerAnimated:completion:
的调用,您可以通过查找堆栈来做到这一点。下面是解决此问题的实现。
上面提到的解决方案不起作用,因为它依赖于查看特定类的调用堆栈符号,该符号在实际设备上运行时被混淆。这是我为解决此问题而采取的不同方法:
- 将
weak
UIDocumentMenuViewController
属性添加到模式视图控制器类。 - 重写模态类中的
-presentViewController:animated:completion:
以检查并查看所呈现的视图控制器是否为UIDocumentMenuViewController
,如果是,请将其设置为步骤 1 中弱属性的值。 - 覆盖
-dismissViewControllerAnimated:completion:
以检查您的弱属性是否nil
,如果它尚未nil
并且您的模态presentedViewController
nil
,则意味着 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)