我做了一个小示例应用程序来展示我的问题。我使用了 Xcode 14.0.1 提供的多平台文档应用程序模板,为此创建了我自己的包文件格式。 我想创建一个在 macOS 和 iPad 上运行的基于文档的应用程序。
在 macOS 上运行时,一切按预期运行。
在 iPad 上,打开应用程序时,会打开文件选择器。
打开现有文件或创建新文件时,屏幕如下所示:
左侧 V 形图标不执行任何操作,而右侧 V 形图标再次显示文档选择器。 左边的、稍微大一点的 V 形在这里做什么?我怎样才能得到它?这是应该向 Apple 报告的框架错误吗?
PS 不要被这个示例应用程序的名称分散注意力——真正的应用程序需要一些导航,我首先想到的是第二个 V 形图标出现的原因——在我为这篇文章构建的示例中,虽然没有导航。所以这第二个 V 形似乎是一个“内置”问题......
为了完整起见,这是我的代码:
import SwiftUI
@main
struct so_DocumentAppWithNavigationShowsMultipleChevronsApp: App {
var body: some Scene {
DocumentGroup(newDocument: so_DocumentAppWithNavigationShowsMultipleChevronsDocument()) { file in
ContentView(document: file.$document)
}
}
}
import UniformTypeIdentifiers
extension UTType {
static var appfroschFile: UTType {
UTType(importedAs: "ch.appfros.so-DocumentAppWithNavigationShowsMultipleChevrons")
}
}
struct so_DocumentAppWithNavigationShowsMultipleChevronsDocument: FileDocument {
var document: Document
init(document: Document = Document(text: "Hello, world!")) {
self.document = document
}
static var readableContentTypes: [UTType] { [.appfroschFile] }
init(configuration: ReadConfiguration) throws {
guard let fileWrappers = configuration.file.fileWrappers
else {
throw CocoaError(.fileReadCorruptFile)
}
guard let documentFileWrapper = fileWrappers["document"],
let data = documentFileWrapper.regularFileContents,
let string = String(data: data, encoding: .utf8)
else {
throw CocoaError(.fileReadCorruptFile)
}
document = try JSONDecoder().decode(Document.self, from: data)
}
func fileWrapper(configuration: WriteConfiguration) throws -> FileWrapper {
let data = try JSONEncoder().encode(document)
let documentFileWrapper = FileWrapper(regularFileWithContents: data)
let mainFileWrapper = FileWrapper(directoryWithFileWrappers: [
"document": documentFileWrapper
])
return mainFileWrapper
}
}
struct Document: Codable {
var text: String
}
struct ContentView: View {
@Binding var document: so_DocumentAppWithNavigationShowsMultipleChevronsDocument
var body: some View {
TextEditor(text: $document.document.text)
}
}
使用在 iOS 16.1 的 iPad 模拟器上运行的 Xcode 14.1 (14B47) 时,可以看到默认的基于文档的应用程序存在相同的问题。所以绝对是一个错误(并且值得向 A 报告)。
据猜测,第二个无功能的后退按钮是用于在侧栏中导航的后退按钮。处理文档时不显示的逻辑已被破坏。
幸运的是,该错误的简单解决方法是使用
toolbarRole
修饰符显式指定工具栏的角色,例如
@main
struct so_DocumentAppWithNavigationShowsMultipleChevronsApp: App {
var body: some Scene {
DocumentGroup(newDocument: so_DocumentAppWithNavigationShowsMultipleChevronsDocument()) { file in
ContentView(document: file.$document)
.toolbarRole(.navigationStack) // <-- Specifying this gets rid of double chevron on iOS
}
}
}
不要使用NavigationView,使用NavigationStack