Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
178 views
in Technique[技术] by (71.8m points)

ios - Can't select a folder with UIViewRepresentable & UIDocumentPicker

I'm trying to create a picker for a user to choose a folder in a SwiftUI app. However, there doesn't seem to be any SwiftUI document picker yet so I was attempting to use UIViewRepresentable to display a document picker using the folder document picker outlined here: https://developer.apple.com/documentation/uikit/view_controllers/providing_access_to_directories. However, as seen in the image below I'm not actually able to select the folder in any way - am I missing specific to use the picker with SwiftUI?

limit

FolderPicker code:

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
        }
    }
}

which is in a TestView:

struct TestView: View {
    @State var displayPicker = false

    var body: some View {
        Button(action: {displayPicker.toggle}, label: "toggle")
            .sheet(isPresented: $showPicker) {
                FolderPicker(folderURL: $url)
            }
    }
}
question from:https://stackoverflow.com/questions/65946464/cant-select-a-folder-with-uiviewrepresentable-uidocumentpicker

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

kUTTypeFolder is not a string.

The correct way is


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

The constant kUTTypeFolder comes from import CoreServices.

Also, public init(documentTypes allowedUTIs: [String], in mode: UIDocumentPickerMode) and optional func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentAt url: URL)is deprecated

So use, public convenience init(forOpeningContentTypes contentTypes: [UTType]) and optional func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL])

Final code is :

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
        }
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...