web-dev-qa-db-fra.com

Comment ouvrir la boîte de dialogue de fichier avec SwiftUI sur la plate-forme "UIKit pour Mac"?

NSOpenPanel n'est pas disponible sur la plate-forme "UIKit pour Mac": https://developer.Apple.com/documentation/appkit/nsopenpanel

Si Apple ne fournit pas de méthode intégrée, je suppose que quelqu'un créera une bibliothèque basée sur SwiftUI et FileManager qui affiche la boîte de dialogue pour sélectionner les fichiers.

5
Ngoc Dao

Voici une solution pour sélectionner un fichier pour macOS avec Catalyst et UIKit

Dans votre vue swiftUI:

Button("Choose file") {
    let picker = DocumentPickerViewController(
        supportedTypes: ["log"], 
        onPick: { url in
            print("url : \(url)")
        }, 
        onDismiss: {
            print("dismiss")
        }
    )
    UIApplication.shared.windows.first?.rootViewController?.present(picker, animated: true)
}

La classe DocumentPickerViewController:

class DocumentPickerViewController: UIDocumentPickerViewController {
    private let onDismiss: () -> Void
    private let onPick: (URL) -> ()

    init(supportedTypes: [String], onPick: @escaping (URL) -> Void, onDismiss: @escaping () -> Void) {
        self.onDismiss = onDismiss
        self.onPick = onPick

        super.init(documentTypes: supportedTypes, in: .open)

        allowsMultipleSelection = false
        delegate = self
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

extension DocumentPickerViewController: UIDocumentPickerDelegate {
    func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
        onPick(urls.first!)
    }

    func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) {
        onDismiss()
    }
}
1
Anthony

Il peut ne pas être présent en tant que composant SwiftUI prêt à l'emploi, mais vous pouvez l'utiliser comme suit:

struct ContentView : View {

    @State var selectedURL: URL?

    var body: some View {
        VStack {
            if selectedURL != nil {
                Text("Selected: \(selectedURL!.absoluteString)")
            } else {
                Text("No selection")
            }
            Button(action: {
                let panel = NSOpenPanel()
                DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
                    let result = panel.runModal()
                    if result == .OK {
                        self.selectedURL = panel.url
                    }
                }
            }) {
                Text("Select file")
            }
        }
        .frame(width: 640, height: 480)
    }

}
0
Matteo Pacini