Как открыть файл диалога с SwiftUI на платформе "UIKit для Mac"?
NSOpenPanel недоступен на платформе "UIKit для Mac": https://developer.apple.com/documentation/appkit/nsopenpanel
Если Apple не предоставляет встроенный способ, я предполагаю, что кто-то создаст библиотеку на основе SwiftUI и FileManager, которая показывает диалог для выбора файлов.
2 ответа
Вот решение для выбора файла для macOS с Catalyst и UIKit
В вашем представлении 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)
}
Класс 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()
}
}
Обе UIDocumentPickerViewController
а также UIDocumentBrowserViewController
работа в Catalyst. Используйте их точно так же, как на iOS, и они будут "волшебным образом" отображаться в стандартных диалоговых окнах открытия / сохранения Mac.
Хороший пример здесь, если вам это нужно: https://appventure.me/guides/catalyst/how/open_save_export_import.html
Это может не присутствовать как из коробки SwiftUI
компонент, но вы можете использовать его следующим образом:
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)
}
}