【问题标题】:Swift UI 2 DocumentGroup get navigation bar buttons actionsSwift UI 2 DocumentGroup 获取导航栏按钮操作
【发布时间】: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)
}

}

【问题讨论】:

    标签: swiftui ios14 documentgroup


    【解决方案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)
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-06-25
        • 2018-07-21
        • 2022-12-05
        • 2020-05-15
        • 1970-01-01
        • 1970-01-01
        • 2013-05-20
        • 2019-04-12
        相关资源
        最近更新 更多