SwiftUI Picker is looking very bad on OSX especially when dealing with long item lists
Swiftui Picker on OSX with a long item list
And since did find any solution to limit the number of item displayed in by Picker on Osx , I decided to interface NSComboBox to SwiftUI
Everythings looks fine until the selection index is modified programmatically using the @Published index of the Observable Comboselection class instance (see code below) :
- the updateNSView function of the NSViewRepresentable instance is called correctly then (print message visible on the log)
combo.selectItem(at: selected.index)
combo.selectItem(at: selected.index)
combo.objectValue = combo.objectValueOfSelectedItem
print("populating index change \(selected.index) to Combo : (String(describing: combo.objectValue))")
is executed correctly and the printed log shows up the correct information
But the NSComboBox textfield is not refreshed with the accurate object value
Does somebody here have an explanation ?? ; is there something wrong in code ??
here the all code :
import SwiftUI
class ComboSelection : ObservableObject {
@Published var index : Int
init( index: Int ) {
self.index = index
}
func newSelection( newIndex : Int ) {
index = newIndex
}
}
//
// SwiftUI NSComboBox component interface
//
struct SwiftUIComboBox : NSViewRepresentable {
typealias NSViewType = NSComboBox
var content : [String]
var nbLines : Int
var selected : ComboSelection
final class Coordinator : NSObject ,
NSComboBoxDelegate {
var control : SwiftUIComboBox
var selected : ComboSelection
init( _ control: SwiftUIComboBox , selected : ComboSelection ) {
self.selected = selected
self.control = control
}
func comboBoxSelectionDidChange(_ notification: Notification) {
print ("entering coordinator selection did change")
let combo = notification.object as! NSComboBox
selected.newSelection( newIndex: combo.indexOfSelectedItem )
}
}
func makeCoordinator() -> SwiftUIComboBox.Coordinator {
return Coordinator(self, selected:selected)
}
func makeNSView(context: NSViewRepresentableContext<SwiftUIComboBox>) -> NSComboBox {
let returned = NSComboBox()
returned.numberOfVisibleItems = nbLines
returned.hasVerticalScroller = true
returned.usesDataSource = false
returned.delegate = context.coordinator // Important : not forget to define delegate
for key in content{
returned.addItem(withObjectValue: key)
}
return returned
}
func updateNSView(_ combo: NSComboBox, context: NSViewRepresentableContext<SwiftUIComboBox>) {
combo.selectItem(at: selected.index)
combo.objectValue = combo.objectValueOfSelectedItem
print("populating index change \(selected.index) to Combo : \(String(describing: combo.objectValue))")
}
}