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 和切换到后台

在 SwiftUI DocumentGroup macOS 中创建并打开一个新文档

如何使用 SwiftUI DocumentGroup 读取大文件而不制作临时副本?

FacebookSDK(4.7) 自定义登录 UI 按钮 - Swift 2.0

Swift UI 2.0:如何设置此通知?