如何将关闭按钮从 swiftui 视图的主要结构(由 uihostingviewcontroller 呈现)分离到它自己的结构?

How to separate a dismiss button from the main struct of a swiftui view (that is presented by a uihostingviewcontroller) to its own struct?

我正在使用按钮显示和关闭 swiftUI 视图,它工作正常。

swiftUI 视图:

struct SmartG_SwiftUI: View {
    var dismissAction: (() -> Void)  
    var body: some View {
       Button(action: {
            dismissAction()
       }) {}
    }
}

我以这种方式展示 UIKit 的 SwiftUI 视图控制器:

let hostingVC = UIHostingVC(rootView: SmartG_SwiftUI(dismissAction: {
                vc?.dismiss( animated: true, completion: nil )
            }))
vc?.present(hostingVC, animated: true, completion: nil)

我的问题是,如何将此按钮放在单独的结构中?所以为了有这样的东西:

struct SmartG_SwiftUI: View {
        var dismissAction: (() -> Void)  
        Header()
}

struct Header: View {
     Button(action: {
            dismissAction() //unknown here
       }) {}
}

SwiftUI 不是手动执行您自己的关闭操作并将其传递进来,而是通过环境变量提供了自己的关闭操作。我还没有在托管控制器的基础上使用过它,但反过来也没有看到任何迹象表明它 工作... (编辑:有双-已检查并且绝对适用于包装在 UIHostingController 中并通过 UIViewController.present(_:animation:completion:) 呈现的 SwiftUI 视图。)

一般做法是:

struct MyView: View {
  @Environment(\.dismiss) var dismiss

  var body: some View {
    Button {
      dismiss()
    } label: {
      Text("Close")
    }
  }
}

但这不一定是您的托管控制器中的最顶层视图;因为关闭操作在环境中,所以它也可以在您的 Header 视图中使用。

请注意,对于 iOS 13 或 14,语法有点冗长:

struct MyView: View {
  @Environment(\.presentationMode) var presentationMode

  var body: some View {
    Button {
      presentationMode.wrappedValue.dismiss()
    } label: {
      Text("Close")
    }
  }
}