首页 > 解决方案 > 带有 TextField 的 macOS SwiftUI 弹出框在首次编辑时关闭

问题描述

我正在构建一个macOS SwiftUI 应用程序。在其中,我有一个popover与一个TextField。有TextField一个绑定更新 anObservableObject然后将其值传播回 aNavigationViewDetail View.

在第一个键盘输入 时TextField,弹出框关闭。 但是,在所有后续条目中,弹出框保持打开状态。

我也用 a 试过了DatePicker,结果一样,所以不限于TextField条目。

请注意,在iOS上运行相同的代码时不会发生这种情况(在 iPhone 上,弹出框显示为工作表或在 iPad 上,它们是弹出框)。

我已经包含了一个最小的例子。

任何人都知道如何避免在第一次编辑时关闭弹出窗口?

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

    var window: NSWindow!

    func applicationDidFinishLaunching(_ aNotification: Notification) {
        let contentView = ContentView(store: AppState())

        window = NSWindow(
            contentRect: NSRect(x: 0, y: 0, width: 480, height: 300),
            styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView],
            backing: .buffered, defer: false)
        window.center()
        window.setFrameAutosaveName("Main Window")
        window.contentView = NSHostingView(rootView: contentView)
        window.makeKeyAndOrderFront(nil)
    }

}

class AppState : ObservableObject {
    @Published var models : [String:Model] = ["1" : Model(id: "1", title: "June 14"),
                                              "2" : Model(id: "2", title: "July 21"),
                                              "3" : Model(id: "3", title: "Sept 5")]
    
    func changeTitle(key: String, newTitle: String) {
        guard var model = self.models[key] else {
            return
        }
        model.title = newTitle
        self.models[key] = model
    }
}

struct Model {
    var id : String
    var title: String
}


struct ContentView: View {
    @ObservedObject var store : AppState
    
    var body: some View {
        NavigationView {
            VStack {
                List {
                    ForEach(Array(store.models.values), id: \.id) { model in
                        NavigationLink(destination: DetailView(model: model,
                                                           changeTitle: { title in
                                                                self.store.changeTitle(key: model.id, newTitle: title)
                        })) {
                            VStack(alignment: .leading) {
                                Text(model.title).font(.headline)
                            }.padding(.vertical, 8)
                        }
                    }
                }.frame(minWidth: 150, idealWidth: 200, maxWidth: 200, maxHeight: .infinity)
            }
            
            EmptyView()
                .frame(maxWidth: .infinity, maxHeight: .infinity)
        }
    }
}

struct DetailView : View {
    var model : Model
    var changeTitle: (String) -> Void
    
    @State private var showPopover = false
    
    var customBinding : Binding<String> {
        Binding<String>(get: { self.model.title }, set: { newValue in
            self.changeTitle(newValue)
        })
    }
    
    var body: some View {
        VStack {
            Text(model.title)
            Button("Edit") {
                self.showPopover.toggle()
            }.popover(isPresented: self.$showPopover) {
                TextField("Text", text: self.customBinding)
                    .frame(minWidth: 300)
                .padding()
            }
        }
            .frame(maxWidth: .infinity, maxHeight: .infinity)
    }
}

标签: macosswiftuinspopover

解决方案


推荐阅读