I'm working on a macOS SwiftUI app. It has a "File->Open Location…" menu command that uses a Segue in IB to modally present an NSWindowController that contains an NSHostingController subclass. My subclass looks like this:
class
OpenLocationController: NSHostingController<OpenLocationView>
{
@objc
required
dynamic
init?(coder: NSCoder)
{
super.init(coder: coder, rootView: OpenLocationView())
}
}
and my view looks like this:
struct
OpenLocationView : View
{
@State private var location: String = ""
var body: some View
{
VStack
{
HStack
{
Text("Movie Location:")
TextField("https://", text: $location)
}
HStack
{
Spacer()
Button("Cancel") { /* dismiss window */ }
Button("Open") { }
}
}
.padding()
.frame(minWidth: 500.0)
}
}
I tried adding a property @Environment(\\.presentationMode) var presentationMode
and calling self.presentationMode.wrappedValue.dismiss()
in the button action, but it has no visible effect.
How do I dismiss this window when the user clicks Cancel?
Here is possible approach. Tested with Xcode 11.2 / macOS 15.0.
class
OpenLocationController: NSHostingController<OpenLocationView>
{
@objc
required
dynamic
init?(coder: NSCoder)
{
weak var parent: NSViewController? = nil // avoid reference cycling
super.init(coder: coder, rootView:
OpenLocationView(parent: Binding(
get: { parent },
set: { parent = $0 })
)
)
parent = self // self usage not allowed till super.init
}
}
struct
OpenLocationView : View
{
@Binding var parent: NSViewController?
@State private var location: String = ""
var body: some View
{
VStack
{
HStack
{
Text("Movie Location:")
TextField("https://", text: $location)
}
HStack
{
Spacer()
Button("Cancel") {
self.parent?.dismiss(nil) // if shown via NSViewController.present
// self.parent?.view.window?.performClose(nil) // << alternate
}
Button("Open") { }
}
}
.padding()
.frame(minWidth: 500.0)
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.