无法使用 UIViewRepresentable 和 UIDocumentPicker 选择文件夹

Posted

技术标签:

【中文标题】无法使用 UIViewRepresentable 和 UIDocumentPicker 选择文件夹【英文标题】:Can't select a folder with UIViewRepresentable & UIDocumentPicker 【发布时间】:2021-01-28 23:03:53 【问题描述】:

我正在尝试为用户创建一个选择器,以便在 SwiftUI 应用程序中选择一个文件夹。但是,似乎还没有任何 SwiftUI 文档选择器,因此我尝试使用UIViewRepresentable 来显示使用此处概述的文件夹文档选择器的文档选择器:https://developer.apple.com/documentation/uikit/view_controllers/providing_access_to_directories。但是,如下图所示,我实际上无法以任何方式选择文件夹 - 我是否缺少将选择器与 SwiftUI 一起使用的特定内容?

FolderPicker代码:

struct FolderPicker: UIViewControllerRepresentable 
    @Binding var folderURL: String?
    
    func makeCoordinator() -> Coordinator 
        return FolderPicker.Coordinator(parent: self)
    
    
    func makeUIViewController(context: UIViewControllerRepresentableContext<FolderPicker>) -> UIDocumentPickerViewController 
        let picker = UIDocumentPickerViewController(documentTypes: ["kUTTypeFolder"], in: .import)
        picker.delegate = context.coordinator
        return picker
    
    
    func updateUIViewController(_ uiViewController: UIDocumentPickerViewController, context: UIViewControllerRepresentableContext<FolderPicker>) 
    
    class Coordinator: NSObject, UIDocumentPickerDelegate 
        var parent: FolderPicker
        
        init(parent: FolderPicker) 
            self.parent = parent
        
        
        internal func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentAt url: URL)
            print(url)
            parent.folderURL = url.absoluteString
        
    

TestView:

struct TestView: View 
    @State var displayPicker = false

    var body: some View 
        Button(action: displayPicker.toggle, label: "toggle")
            .sheet(isPresented: $showPicker) 
                FolderPicker(folderURL: $url)
            
    

【问题讨论】:

这是你的答案***.com/a/65751595/14733292 吗? 【参考方案1】:

kUTTypeFolder 不是字符串。

正确的做法是


let picker = UIDocumentPickerViewController(documentTypes: [kUTTypeFolder as String], in: .import)

常量kUTTypeFolder 来自import CoreServices

另外public init(documentTypes allowedUTIs: [String], in mode: UIDocumentPickerMode)optional func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentAt url: URL) 已弃用

所以使用public convenience init(forOpeningContentTypes contentTypes: [UTType])optional func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL])

最终代码是:

struct FolderPicker: UIViewControllerRepresentable 
    
    @Binding var folderURL: String?
    
    func makeCoordinator() -> Coordinator 
        return FolderPicker.Coordinator(parent: self)
    
    
    func makeUIViewController(context: UIViewControllerRepresentableContext<FolderPicker>) -> UIDocumentPickerViewController 
        let picker = UIDocumentPickerViewController(forOpeningContentTypes: [.folder])
        picker.delegate = context.coordinator
        return picker
    
    
    func updateUIViewController(_ uiViewController: UIDocumentPickerViewController, context: UIViewControllerRepresentableContext<FolderPicker>) 
    
    class Coordinator: NSObject, UIDocumentPickerDelegate 
        var parent: FolderPicker
        
        init(parent: FolderPicker) 
            self.parent = parent
        
        func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) 
            guard let url = urls.first else 
                return
            
            print(url)
            parent.folderURL = url.absoluteString
        
    

【讨论】:

以上是关于无法使用 UIViewRepresentable 和 UIDocumentPicker 选择文件夹的主要内容,如果未能解决你的问题,请参考以下文章

无法使 UIViewRepresentable 的 CustomView 在 SwiftUI 中正常工作

无法将点击手势识别器添加到 SwiftUI MKMapView UIViewRepresentable

SwiftUI:类型不符合协议“UIViewRepresentable”

如何在 SwiftUI 中使 UIViewRepresentable 在 tvOS 上具有焦点?

如何使 UIViewRepresentable @ViewBuilder 与动态内容一起使用?

协调器不适用于 UIViewRepresentable?