Swift NSCombobox DataSource Sample Code
Created By: Debasis Das (2-Feb-2016)
In this article we will implement the NSComboBoxDataSource in Swift with Autocomplete feature.
Most of the cases the NSComboBox has a static list of elements that is shown and thus the values can be stored in an array or are created in the XIB itself. however there will be scenarios when a functionality is desired where the combo box is populated at run time and thus we would need a datasource implementation.
The datasource can be implemented either in a ViewController, a window controller, a model controller or a stand alone datasource file.
In this sample code we have implemented the datasource in the app delegate.
A datasource implementation is also required to implement the auto complete functionality that is achieved through implementing the completedString method of the NSComboBox
// AppDelegate.swift
// NSComboBoxDataSource
// Created by Debasis Das on 02/02/16.
// Copyright © 2016 Knowstack. All rights reserved.
import Cocoa
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate, NSComboBoxDataSource,NSComboBoxDelegate,NSControlTextEditingDelegate {
@IBOutlet weak var window: NSWindow!
@IBOutlet weak var comboBox: NSComboBox!
var dataArray = []
var filteredDataArray:NSMutableArray = []
func applicationDidFinishLaunching(aNotification: NSNotification)
{
self.comboBox.usesDataSource = true
self.comboBox.setDelegate(self)
self.comboBox.dataSource = self
self.comboBox.completes = true
self.dataArray = ["Debasis","John","Jane","Mary","Bill","William","Steve"]
self.filteredDataArray = NSMutableArray(array:self.dataArray)
}
func applicationWillTerminate(aNotification: NSNotification)
{
}
func numberOfItemsInComboBox(aComboBox: NSComboBox) -> Int{
return self.filteredDataArray.count
}
func comboBox(aComboBox: NSComboBox, objectValueForItemAtIndex index: Int) -> AnyObject{
return self.filteredDataArray[index] as! String
}
func comboBox(aComboBox: NSComboBox, indexOfItemWithStringValue string: String) -> Int{
return self.filteredDataArray.indexOfObject(string)
}
func comboBox(aComboBox: NSComboBox, completedString string: String) -> String?{
print("completedString")
var returnString = ""
for var dataString in self.dataArray{
if dataString.commonPrefixWithString(string, options: NSStringCompareOptions.CaseInsensitiveSearch).lengthOfBytesUsingEncoding(NSUTF8StringEncoding) == string.lengthOfBytesUsingEncoding(NSUTF8StringEncoding)
{
returnString = dataString as! String
self.filterDataArray(string)
return returnString
}
}
if returnString.isEmpty{
self.comboBox.stringValue = ""
}
self.filterDataArray(string)
return returnString
}
func filterDataArray(string:String){
print("filterDataArray \(string)")
self.filteredDataArray = []
if (string.isEmpty || string == "" || string == " ")
{
self.filteredDataArray = NSMutableArray(array: self.dataArray)
}
else
{
for var i = 0; i < dataArray.count ; i++ {
var searchNameRange = dataArray[i].rangeOfString(string, options: NSStringCompareOptions.CaseInsensitiveSearch)
if searchNameRange.location != NSNotFound {
self.filteredDataArray.addObject(dataArray[i])
}
}
if self.filteredDataArray.count == 0{
self.filteredDataArray = NSMutableArray(array: self.dataArray)
}
}
print(self.filteredDataArray)
self.comboBox.reloadData()
}
func comboBoxWillPopUp(notification: NSNotification) {
if let searchStr = notification.object?.string{
self.filterDataArray(searchStr)
}
}
override func controlTextDidChange(obj: NSNotification) {
if (obj.object?.isEqual(self.comboBox) != nil)
{
self.filterDataArray(self.comboBox.stringValue)
}
else{
print("this should not get printed")
}
}
}
Well explained!
Hello,
I am having a problem implementing your very clear example. I implemented my NSComboBox in ViewController.swift. And these lines will not compile:
self.comboBox.setDelegate(self)
self.comboBox.dataSource = self
self.comboBox.completes = true
I get the following error statements for each line respectively:
– ViewController.swift:22:14: Value of type ‘NSComboBoxCell’ has no member ‘setDdelegate’
– ViewController.swift:23:14: Value of type ‘(NSComboBox, objectValueForItemAt: Int) -> AnyObject?’ has no member ‘dataSource’
– ViewController.swift:24:14: Value of type ‘(NSComboBox, objectValueForItemAt: Int) -> AnyObject?’ has no member ‘completes’
I could not find any equivalents for these members in my version of Xcode.
I am using Xcode Version 7.3.1 (7D1014)
Any help or advice would be appreciated.
Thank you