代码之家  ›  专栏  ›  技术社区  ›  user2606782

iOS未调用UIDocumentPickerDelegate方法(didPickDocumentsAt)

  •  1
  • user2606782  · 技术社区  · 5 年前

    我有一个关于DocumentPickerViewController没有调用委派方法的问题,这是背景,我只需要从我的文件应用程序导入任何可用的资源,因此我使用UIDocumentPickerViewController。

    我有一个单独的ViewController,我将documentPickerViewController的视图添加为子视图,并将其添加为委托。我的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)
    

    现在我看到pickercontroller打开,当我点击Cancel时 documentPickerWasCancelled 但当我选择一个文件时 documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL] 不叫。

    我试着进一步深入,让我惊讶的是,如果我像这样直接显示pickerViewController,我看到的不是显示我的ViewController,而是将picker的视图添加为子视图

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

    这两个委托方法的调用都很好。我不明白为什么。有人能帮帮我吗!!提前谢谢!!

    1 回复  |  直到 5 年前
        1
  •  1
  •   Leo    5 年前

    所以我遇到了完全相同的问题 documentPickerWasCancelled 已调用委托方法,但 didPickDocumentsAt 不会接到电话。

    同样值得注意的是,当我将所有委派/表示逻辑移到我的基本视图控制器中时,UIPickerDelegate方法按预期工作。这让我知道,没有任何配置类型问题阻碍功能。

    我不确定问题出在哪里,但如果文档选择器出现在复杂的视图层次结构上,似乎会出现一些问题。

    为了解决这个问题,我最终创建了一个新窗口,并在那里展示了文档选择器:

    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)
        }
    
        2
  •  0
  •   Tomte    5 年前

    答案很简单:这是从UIViewController继承的。如果只是将viewController的视图添加到视图中,则不会调用委托方法。ViewController有自己的生命周期。请在此阅读: https://developer.apple.com/documentation/uikit/uidocumentpickerviewcontroller

    所以,为自己的错误道歉。当然,您可以添加一个子viewController,只显示其视图。但是:我认为这不应该是用例。这是一款符合苹果自身设计指南的全屏ViewController。话虽如此,你应该提出:

    func addPicker() {
        var documentPickerController: UIDocumentPickerViewController!
    
        documentPickerController = UIDocumentPickerViewController(documentTypes: [String(kUTTypePDF)], in: .import)
        documentPickerController.delegate = self
        documentPickerController.allowsMultipleSelection = false
    
        present(documentPickerController, animated: true, completion: nil)
    }
    

    在调用委托之前,开发人员发现视图已被删除,因此存在一些缺陷。据我所知,这种行为是在ios11中引入的,在展示viewController时也会出现。我不能确定这是否是固定的,也不能确定这一行为是否与将其显示为子视图有关。(我认为它在某种程度上是固定的,因为它与显示的viewController一起工作)

    不管怎样,你应该按照上面写的那样展示,你就可以开始了。

        3
  •  0
  •   Daniele Galiotto - gali8    4 年前

    原因是,如果不将委托放入函数外部的变量中,委托将被解除分配。

    如果您处于静态环境中,则可以创建静态var委托:例如DocumentPickerDelegateClass;否则,在UIViewController中,只需创建var委托:DocumentPickerDelegateClass

    在任何情况下,都要将var放在不能解除分配的顶部。 选择“静态”选项时要小心,必须小心使用。

    推荐文章