简体   繁体   English

iOS 未调用 UIDocumentPickerDelegate 方法(didPickDocumentsAt)

[英]UIDocumentPickerDelegate method(didPickDocumentsAt) not called by iOS

I have a query regarding delegate method not been getting called for DocumentPickerViewController, here's the background, I just need to import the resource whatever available from my Files App and for that reason i am using UIDocumentPickerViewController.我有一个关于没有为 DocumentPickerViewController 调用委托方法的查询,这是背景,我只需要从我的文件应用程序中导入任何可用的资源,因此我正在使用 UIDocumentPickerViewController。

I have a separate ViewController to which i add documentPickerViewController's view as subview and add it's delegate.我有一个单独的 ViewController,我将 documentPickerViewController 的视图添加为子视图并将其添加为委托。 My ViewController's code goes like this.我的 ViewController 的代码是这样的。

var documentPickerController: UIDocumentPickerViewController!
  let supportedUTI = [kUTTypeImage,kUTTypeSpreadsheet,kUTTypePresentation,kUTTypeDatabase,kUTTypeFolder,kUTTypeZipArchive,kUTTypeVideo, kUTTypeAudiovisualContent]

documentPickerController = UIDocumentPickerViewController.init(documentTypes: supportedUTI as [String], in: .import)
    documentPickerController.delegate = self
    documentPickerController.allowsMultipleSelection = false
    view.addSubview(documentPickerController.view)

Now as i see pickercontroller is opened and when i tap on Cancel documentPickerWasCancelled is called but when i select a file documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL] is not called.现在我看到pickercontroller已打开,当我点击取消时documentPickerWasCancelled被调用,但是当我选择文件时documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]未被调用。

I tried to dip in further to my surprise what i see is instead of showing my ViewController to which i add picker's view as subview if i directly show pickerViewController like this如果我像这样直接显示pickerViewController,我试图进一步深入了解我所看到的是而不是显示我的ViewController

UIDocumentPickerViewController *dc = [[UIDocumentPickerViewController alloc] initWithDocumentTypes:[self UTITypes] inMode:UIDocumentPickerModeImport];
    dc.delegate = self;
    [MainVC presentViewController:dc animated:YES completion:nil];

both the delegate method are called just fine.两个委托方法都被调用得很好。 I don't understand why.我不明白为什么。 Can someone please help me out here!!有人可以在这里帮我吗! Thanks in advance!!提前致谢!!

So I had the exact same issue, the documentPickerWasCancelled delegate method is called but the didPickDocumentsAt would not get called.所以我遇到了完全相同的问题,调用了documentPickerWasCancelled委托方法,但不会调用didPickDocumentsAt

Also of note, when I moved all of the delegation/presentation logic into my base view controller the UIPickerDelegate methods worked as expected.另外值得注意的是,当我将所有委托/演示逻辑移动到我的基本视图控制器中时,UIPickerDelegate 方法按预期工作。 This let me know that there weren't any configuration type issues blocking functionality.这让我知道没有任何配置类型问题阻止功能。

I'm not exactly sure what the problem is but it seems that if the document picker is presented on a complex view hierarchy something breaks.我不确定问题出在哪里,但似乎如果文档选择器出现在复杂的视图层次结构上,就会出现问题。

What I ended up doing to work around this issue was creating a new window and presenting the document picker there:我最终解决此问题的方法是创建一个新窗口并在那里显示文档选择器:

func showDocumentPicker() {

        let documentTypes = ["public.image", "com.adobe.pdf"]

        let picker = UIDocumentPickerViewController(documentTypes: documentTypes, in: .import)
        picker.delegate = self
        picker.allowsMultipleSelection = true
        picker.modalPresentationStyle = .formSheet

        let window = UIWindow(frame: UIScreen.main.bounds)
        let newWindowBaseVC = UIViewController()
        newWindowBaseVC.view.backgroundColor = UIColor.clear
        window.rootViewController = newWindowBaseVC
        window.windowLevel = UIWindow.Level.alert
        window.makeKeyAndVisible()
        newWindowBaseVC.present(picker, animated: false, completion: nil)
    }

The answer is simple: This is inherited from a UIViewController.答案很简单:这是从 UIViewController 继承的。 If you just add the view of the viewController to your view, the delegate methods are not called.如果您只是将 viewController 的视图添加到您的视图中,则不会调用委托方法。 A ViewController has its own lifecycle. ViewController 有自己的生命周期。 Please have a read here: https://developer.apple.com/documentation/uikit/uidocumentpickerviewcontroller请在此处阅读: https ://developer.apple.com/documentation/uikit/uidocumentpickerviewcontroller

So, apologies for being some kind of wrong.所以,为某种错误道歉。 For sure you can add a sub-viewController showing just its view.当然,您可以添加一个仅显示其视图的子视图控制器。 But: I think that shouldn't be the use-case.但是:我认为这不应该是用例。 It is a full screen ViewController conforming to design guides from apple itself.它是一个全屏 ViewController 符合苹果本身的设计指南。 That being said, you should present it with:话虽这么说,您应该向它展示:

func addPicker() {
    var documentPickerController: UIDocumentPickerViewController!

    documentPickerController = UIDocumentPickerViewController(documentTypes: [String(kUTTypePDF)], in: .import)
    documentPickerController.delegate = self
    documentPickerController.allowsMultipleSelection = false

    present(documentPickerController, animated: true, completion: nil)
}

There are some bugs filed where developer discovered that the view is being dismissed before the delegate is called.有一些错误提交,开发人员发现在调用委托之前视图被关闭。 As far as I have seen, this behavior was introduced with ios11 and occured also when the viewController was presented.据我所知,这种行为是在 ios11 中引入的,并且在显示 viewController 时也会发生。 I can't really say if this is fixed or not nor if this behavior is related to show it as a subview.我真的不能说这是否是固定的,也不能说这种行为是否与将其显示为子视图有关。 (I think it is somehow fixed as it works with a presented viewController) (我认为它在某种程度上是固定的,因为它与呈现的 viewController 一起工作)

Anyway, you should just present it as written above and you are good to go.无论如何,您应该按照上面的说明呈现它,您就可以开始了。

The reason is because the delegate is deallocated if you do not put it in a var outside the function.原因是如果您不将委托放在函数外部的 var 中,则委托将被释放。

If you are in a static environment, you can create a static var delegate: DocumentPickerDelegateClass for example;如果您在静态环境中,则可以创建静态 var 委托:例如 DocumentPickerDelegateClass; otherwise, in a UIViewController just create the var delegate: DocumentPickerDelegateClass否则,在 UIViewController 中只需创建 var 委托: DocumentPickerDelegateClass

In every case, put the var on top, where cannot be deallocated.在任何情况下,都将 var 放在无法释放的位置。 Be careful when you choose the "static" option, you must use it with care.选择“静态”选项时要小心,必须小心使用。

Using iOS 15 I was struck by the same problem, and guess what: although didPickdocumentsAtURL is not called, the deprecated didPickDocumentAtURL is called in this case.在使用 iOS 15 时,我遇到了同样的问题,你猜怎么着:虽然没有调用 didPickdocumentsAtURL,但在这种情况调用了已弃用的 didPickDocumentAtURL。 I'll use that for now as I need single selection only anyway.我现在将使用它,因为无论如何我只需要单选。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM