macOS SwiftUI отклонить модал приложения NSHostingController, представленный через segue из меню? - PullRequest
0 голосов
/ 23 февраля 2020

Я работаю над приложением macOS SwiftUI. Он имеет команду меню «Файл-> Открыть местоположение…», которая использует Segue в IB для модального представления NSWindowController, который содержит подкласс NSHostingController. Мой подкласс выглядит следующим образом:

class
OpenLocationController: NSHostingController<OpenLocationView>
{
    @objc
    required
    dynamic
    init?(coder: NSCoder)
    {
        super.init(coder: coder, rootView: OpenLocationView())
    }
}

, и мой взгляд выглядит так:

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)
    }
}

Я попытался добавить свойство @Environment(\.presentationMode) var presentationMode и вызвать self.presentationMode.wrappedValue.dismiss() в действии кнопки, но оно не имеет видимого эффекта.

Как закрыть это окно, когда пользователь нажимает кнопку Отмена?

1 Ответ

1 голос
/ 23 февраля 2020

Здесь возможен подход. Протестировано с 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)
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...