0

I am presenting and dismissing a swiftUI view with a button, and it works fine.

The swiftUI view:

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

I am presenting the SwiftUI view controller from UIKit, this way:

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

My question is, how could I put this button in a separate struct? So in order to have something like:

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

struct Header: View {
     Button(action: {
            dismissAction() //unknown here
       }) {}
}
Abv
  • 354
  • 2
  • 13

1 Answers1

0

Rather than hand-rolling your own dismiss action and passing it in, SwiftUI does have its own dismiss action available via an environment variable. I’ve not yet used it within a hosting controller basis, but conversely haven’t seen any indication that it doesn’t work... (edit: have double-checked and definitely works for a SwiftUI view wrapped in a UIHostingController and presented via UIViewController.present(_:animation:completion:).)

The general approach is:

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

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

But this doesn’t have to be the topmost view within your hosting controller; because the dismiss action is in the environment, it’ll be available in your Header view as well.

Note that for iOS 13 or 14, the syntax is a little more verbose:

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

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

ScottM
  • 7,108
  • 1
  • 25
  • 42
  • This works great, thanks. It is a lot easier. I also tried to put the button in a separated struct with that presentationMode variable on top and it worked also. The view dismissed, I don't know how to check it was deallocated but I guess it did deallocate. – Abv Dec 08 '21 at 21:25