我有一个导入(和导出)按钮,可以很好地放置在视图中。
var body: some View {
Button(action: {
isImporting = true
}, label: {
Label("Import", systemImage: "square.and.arrow.down")
})
.fileImporter(
isPresented: $isImporting,
allowedContentTypes: [UTType.log, UTType.text, UTType.xml, UTType.zip],
allowsMultipleSelection: true
) { result in
switch result {
case let .success(files):
files.forEach { file in
guard file.startAccessingSecurityScopedResource() else { return }
.../...
file.stopAccessingSecurityScopedResource()
}
case let .failure(error):
print(error)
}
}
}
但我还希望通过 macOS 应用程序中的“文件”菜单使用导入/导出命令。
struct ImportExportCommands: Commands {
@MainActor
var body: some Commands {
CommandGroup(replacing: .importExport) {
Section {
ImportButton()
.modelContainer(mdContainer.sharedModelContainer)
ExportButton()
.modelContainer(mdContainer.sharedModelContainer)
}
}
}
}
执行了操作代码,但没有出现文件对话框。
我没有找到任何关于此的信息,所以我认为这是一件非常愚蠢的事情。
如何通过菜单命令在屏幕上弹出 fileImporter/fileExporter 对话框?
我看到的问题是,您首先需要打开窗口才能使
.fileImporter
修改器起作用,但解决此问题的一种方法是使用 NSOpenPanel
代替。
类似这样的:
struct ImportExportCommands: Commands {
@Environment(\.openWindow) private var openWindows
@MainActor
var body: some Commands {
CommandGroup(replacing: .importExport) {
Section {
Button("Import") {
selectImportFiles()
}
}
}
}
private func selectImportFiles() {
let openPanel = NSOpenPanel()
openPanel.title = "Import files"
openPanel.prompt = "Import"
openPanel.canChooseFiles = true
openPanel.allowsMultipleSelection = true
openPanel.allowedContentTypes = [UTType.log, UTType.text, UTType.xml, UTType.zip]
openPanel.begin { result in
if result == .OK {
for fileUrl in openPanel.urls {
print(fileUrl.absoluteString)
}
}
}
}
}
我在 SwiftUI 应用程序中遇到了类似的问题。对我有用的是向菜单视图添加聚焦绑定。
添加焦点绑定需要您执行以下操作:
FocusedValues
结构的扩展。焦点值键结构必须符合
FocusedValueKey
协议。为重点值类型提供类型别名。以下代码为 SwiftUI 文档结构创建一个焦点值类型:
struct DocumentFocusedValueKey: FocusedValueKey {
typealias Value = Binding<Document>
}
FocusedValues
扩展的计算属性要求您为您创建的焦点值键结构添加 getter 和 setter。
extension FocusedValues {
var document: DocumentFocusedValueKey.Value? {
get {
return self[DocumentFocusedValueKey.self]
}
set {
self[DocumentFocusedValueKey.self] = newValue
}
}
}
使用
@FocusedBinding
属性包装器将焦点绑定添加到菜单视图。
@FocusedBinding(\.document) var document: Document?
您在
@FocusedBinding
之后放置的值是您作为 FocusedValues
的扩展添加的计算属性的名称。
使用
.focusedSceneValue
修改器设置聚焦场景值。以下示例将聚焦场景的值设置为基于文档的应用程序中的文档:
.focusedSceneValue(\.document, file.$document)
在此示例中,您将在应用程序结构中设置
.focusedSceneValue
修饰符。