gpt4 book ai didi

macos - 如何使用 swiftUI 获取 ComboBox

转载 作者:行者123 更新时间:2023-12-02 02:09:01 28 4
gpt4 key购买 nike

有没有办法在 SwiftUI 中创建一个 NSComboBox?当我使用 Picker 时,在 MacOS 下创建了一个 NSPopUpButton

我已经试过了:

var body: some View {
Picker("Test:", selection: $selected) {
ForEach(1..<10) { i in
Text(String(i))
}
}
.padding()
}

但这会让我得到这个:

enter image description here

但我需要一个 ComboBox,我可以在其中输入文本以及从列表中进行选择。

如果 SwiftUI 没有NSComboBox 集成为 NSViewRepresentable,这甚至可能吗?

我已经检查了以下问题:SwiftUI Custom Picker / ComboBox但它是关于自定义选择器而不是 NSComboBox。

最佳答案

VDK组合框

使用 NSViewRepresentable 并不像我预期的那么糟糕。下面是 SwiftUI 的 NSComboBox 的完整实现:​​

import Foundation
import SwiftUI


struct VDKComboBox: NSViewRepresentable
{
// The items that will show up in the pop-up menu:
var items: [String]

// The property on our parent view that gets synced to the current stringValue of the NSComboBox, whether the user typed it in or selected it from the list:
@Binding var text: String


func makeCoordinator() -> Coordinator {
return Coordinator(self)
}


func makeNSView(context: Context) -> NSComboBox
{
let comboBox = NSComboBox()
comboBox.usesDataSource = false
comboBox.completes = false
comboBox.delegate = context.coordinator
comboBox.intercellSpacing = NSSize(width: 0.0, height: 10.0) // Matches the look and feel of Big Sur onwards.
return comboBox
}


func updateNSView(_ nsView: NSComboBox, context: Context)
{
nsView.removeAllItems()
nsView.addItems(withObjectValues: items)

// ComboBox doesn't automatically select the item matching its text; we must do that manually. But we need the delegate to ignore that selection-change or we'll get a "state modified during view update; will cause undefined behavior" warning.
context.coordinator.ignoreSelectionChanges = true
nsView.stringValue = text
nsView.selectItem(withObjectValue: text)
context.coordinator.ignoreSelectionChanges = false
}
}



// MARK: - Coordinator


extension VDKComboBox
{
class Coordinator: NSObject, NSComboBoxDelegate
{
var parent: VDKComboBox
var ignoreSelectionChanges: Bool = false

init(_ parent: VDKComboBox) {
self.parent = parent
}


func comboBoxSelectionDidChange(_ notification: Notification)
{
if !ignoreSelectionChanges,
let box: NSComboBox = notification.object as? NSComboBox,
let newStringValue: String = box.objectValueOfSelectedItem as? String
{
parent.text = newStringValue
}
}


func controlTextDidEndEditing(_ obj: Notification)
{
if let textField = obj.object as? NSTextField
{
parent.text = textField.stringValue
}
}
}
}

使用它:

struct MyView: View
{
@State var comboBoxText: String = ""

var body: some View
{
VDKComboBox(items: ["one", "two", "three"], text: $comboBoxText)
.padding()
}
}

当然,您将动态填充项目列表;硬编码的字符串数组只是一个简单的例子。

备选方案

我知道你明确排除了 NSViewRepresentable,但我尝试了很多其他方法来模仿 NSComboBox,包括:

  • TextField 顶部的 SwiftUI Button.trailing 对齐
  • 动态交换 TextFieldPicker
  • 链接到 TextField 的自定义 Popover

所有这些都以某种方式看起来“陌生”。由于 NSViewRepresentable 并不是那么糟糕,所以这就是我的决定。它可能会在未来帮助其他人,所以我将我的实现放在这里,即使你想要一个不依赖于 NSViewRepresentable 的实现。

关于macos - 如何使用 swiftUI 获取 ComboBox,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67956554/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com