Hi, I just did a NSTextField with auto complete that show a cities menu bar the problem is when I typing the first letter, the focus change to the menubar and if I try to write another letter it just replace the first letter and not add it how can I fix it?
Thank you!
class NSTextFieldAuto: NSTextField, NSMenuDelegate, NSTextFieldDelegate {
var suggestionMenu: NSMenu?
var selectedSuggestionIndex: Int?
override func awakeFromNib() {
super.awakeFromNib()
self.delegate = self
self.suggestionMenu = NSMenu()
self.suggestionMenu?.delegate = self
}
override func mouseDown(with event: NSEvent) {
super.mouseDown(with: event)
// Deselect all text when the text field is clicked
}
override func textDidChange(_ notification: Notification) {
super.textDidChange(notification)
print("Still typing")
updateSuggestionMenu()
showSuggestionMenu()
}
override func textDidEndEditing(_ notification: Notification) {
print("Finished typing")
cityDef.setValue(self.stringValue, forKey: cityDefKey)
}
func updateSuggestionMenu() {
self.suggestionMenu?.removeAllItems()
let searchText = self.stringValue.lowercased()
for (index, city) in allCities.enumerated() {
if city.lowercased().hasPrefix(searchText) {
let item = NSMenuItem(title: city, action: #selector(selectSuggestion(_:)), keyEquivalent: "")
item.target = self
self.suggestionMenu?.addItem(item)
}
}
}
func showSuggestionMenu() {
if let menu = self.suggestionMenu, !menu.items.isEmpty {
let textFieldRect = self.bounds
let origin = NSPoint(x: textFieldRect.origin.x + 100.0, y: textFieldRect.origin.y + textFieldRect.size.height)
menu.autoenablesItems = false
menu.popUp(positioning: nil, at: origin, in: self)
}
}
@objc func selectSuggestion(_ sender: NSMenuItem) {
self.stringValue = sender.title
}
override func cancelOperation(_ sender: Any?) {
self.suggestionMenu?.cancelTracking()
self.window?.becomeFirstResponder()
}
func menuDidClose(_ menu: NSMenu) {
self.window?.makeFirstResponder(self) // Set text field as first responder again
print("Close menu")
}
override func becomeFirstResponder() -> Bool {
let result = super.becomeFirstResponder()
self.selectedSuggestionIndex = nil // Reset selected suggestion index
return result
}
}