Swift UI 2 DocumentGroup 获取导航栏按钮操作
Posted
技术标签:
【中文标题】Swift UI 2 DocumentGroup 获取导航栏按钮操作【英文标题】:Swift UI 2 DocumentGroup get navigation bar buttons actions 【发布时间】:2020-07-18 10:14:07 【问题描述】:我正在将新的“DocumentGroup”场景用于 iOS 14(目前正在开发 Beta)项目,但我真的不这样做'不知道如何检测导航栏中的事件,例如按“
@main struct DocumentAppApp: App
@SceneBuilder var body: some Scene
// Adding of a new document
DocumentGroup(newDocument: DocumentAppDocuments()) file in
ContentView(document: file.$document) // .navigationBarBackButtonHidden(true)
struct ContentView: View
@Binding var document: DocumentAppDocuments
var body: some View
TextEditor(text: $document.text)
【问题讨论】:
【参考方案1】:我最终在文档的ContentView.body
中执行了以下操作:
NavigationView
SideBar(document: $document)
.navigationBarItems(leading: Button("Back")
// figure out how to programmatically go back...
)
Text("Nothing selected")
.navigationBarHidden(true)
我基本上杀死了文档浏览器附带的自动NavigationView
。由于许多原因,这并不理想,其中第一个是我实际上还没有弄清楚如何回去。如果我们可以访问底层的NavigationView
,这样我就可以设置我的侧边栏和我的内容,这不会是一个问题,但到目前为止我在这里也没有成功。
DocumentGroup
有点像半生不熟的垃圾。为什么要推送,而不是呈现在“空”文档上?为什么我不能设置DocumentGroup
等的强调色。我已经为这些项目写了反馈,但谁知道它是否会在发布前得到解决。
最后一个选择是自己接管它,根本不使用DocumentGroup
,将UIDocumentBrowserViewController
用作UIViewControllerRepresentable
,然后继续你的生活。我可能很快就会在这里结束。
更新:
我放弃了DocumentGroup
。这没有任何意义。推送内容?哑的。改变色调?不能。我的应用程序也摆脱了 SwiftUI 应用程序条目,因此我可以完全控制 UIDocumentBrowserViewController,我建议你也这样做。唯一困难的部分是弄清楚如何最好地利用基于UIDocument
的存储,而不是更好地利用FileDocument
SwiftUI 提供的存储。为此,我基本上是这样做的:
final class Document: UIDocument, ObservableObject
var someDocumentProperty: String = ""
willSet
// this updates the SwiftUI view hierarchy
objectWillChange.send()
didSet
// this will autosave whenever you change this property
updateChangeCount(.done)
现在它将完全适用于 SwiftUI 视图,正确保存一切。
【讨论】:
【参考方案2】:完全相同的问题。简而言之,我决定看看是否还有 UIApplication.shared 正在创建,并且当我能够以编程方式返回时,如下所示:
private func goBack()
#if canImport(UIKit)
guard let currentWindow = UIApplication.shared.windows.first,
let documentBrowser = currentWindow
.rootViewController as? UIDocumentBrowserViewController
else
logw(
"<\(#fileID) \(#function)> Failed to retrieve document browser."
)
return
documentBrowser.dismiss(animated: true)
logi("<\(#fileID) \(#function)> the document browser has dismissed it's child.")
#endif
或简化:
`UIApplication.shared.windows.first?.rootViewController?.dismiss(animated: true) print("the document browser has dismissed it's child.") `
【讨论】:
谢谢!一直在寻找一个简单的答案,因为我想保留 DocumentGroup 功能,但放弃内置导航栏。【参考方案3】:我的目标是注入自己的功能,同时保持DocumentGroup
提供的系统后退按钮的外观和感觉。请注意,我的文档视图是UIViewController
,包裹在UIViewControllerRepresentable
中。该解决方案基于 Jason Cardwell 的:
override func viewWillAppear(_ animated: Bool)
super.viewWillAppear(animated)
var systemBackButtonItem = navigationController?.navigationBar.items?[0].leftBarButtonItems?[0]
systemBackButtonItem?.target = self
systemBackButtonItem?.action = #selector(done)
@objc private func done()
UIApplication.shared.windows.first?.rootViewController?.dismiss(animated: true)
print("the document browser has dismissed it's child.")
但请注意,这可能会与 DocumentGroup 提供的某些功能发生冲突。但是,到目前为止,就我而言,一切都很好。另一种选择:
private weak var originalBackButtonTarget: AnyObject?
private var originalBackButtonAction: Selector?
override func viewWillAppear(_ animated: Bool)
super.viewWillAppear(animated)
var systemBackButtonItem = navigationController?.navigationBar.items?[0].leftBarButtonItems?[0]
originalBackButtonTarget = systemBackButtonItem?.target
systemBackButtonItem?.target = self
originalBackButtonAction = systemBackButtonItem?.action
systemBackButtonItem?.action = #selector(done)
@objc private func done()
guard let originalBackButtonAction = originalBackButtonAction else return
originalBackButtonTarget?.perform(originalBackButtonAction, with: self)
【讨论】:
以上是关于Swift UI 2 DocumentGroup 获取导航栏按钮操作的主要内容,如果未能解决你的问题,请参考以下文章
SwiftUI fileExporter 在 DocumentGroup 的工具栏修饰符中用作按钮修饰符时不存在
在 SwiftUI DocumentGroup macOS 中创建并打开一个新文档
如何使用 SwiftUI DocumentGroup 读取大文件而不制作临时副本?