Search code examples
cocoaswift3macos-sierranscombobox

Cocoa Not Calling ViewController Function


I built a viewcontroller with a combobox that has the completion option so that when I type a letter, it finds the first occurence in the list starting with that letter. It works fine. I then copied the code to another view controller and changed the appropriate source information. It doesn't work. I've been comparing the two for a couple days now to see if I missed anything and it all seems OK. I've put in a number of print statements to isolate the problem. This is the console log of a run through both of controllers:

// 1
completed string starting. Tag:  1
// 2
Starting findFirstOccurrence parm string:  m
findFirstOccurrence dataRow:  ["style_id": 61, "name": Ma (She's Making Eyes at Me), "id": 1040, "year_written": <null>, "year_published": <null>, "notes": <null>]
findFirstOccurrence returning:  Ma (She's Making Eyes at Me)
objectValueForItemAt index:  1637
entry:  Ma (She's Making Eyes at Me)
// 3
Entered textShouldEndEditing - tag:  1 selectedRow:  1637
// 4
initializeDialog creditRow:  ["record_id": 485]
completed string starting. Tag:  1
// 5
Starting findFirstOccurrence parm string:  m
findFirstOccurrence dataRow:  ["other_instruments": <null>, "name": Maucha Adnet, "last_name": Adnet, "primary_instrument": vocals, "id": 2368, "first_name": Maucha, "birth_year": <null>, "death_year": <null>, "notes": <null>]
findFirstOccurrence returning:  Maucha Adnet
// 6
Entered textShouldEndEditing - tag:  1 selectedRow:  -1
  1. I activate the controller. The cursor appears in the first field, which is the working combobox
  2. I type the letter m. My findFristOccurance method is called. It returns the string shown. Then my objectValueForItemAt is called. It returns the entry shown.
  3. I hit the tab key. My textShouldEndEditing is called and it's happy and returns a valid response. The cursor moves to the next field.
  4. I exit the view controller - it's a modal dialog - and enter the one that doesn't work. The cursor appears in the first field, which is the non-working combobox.
  5. I type the letter m. My findFristOccurance method is called. It returns the string shown. My objectValueForItemAt is NOT called.
  6. When I tab out of the field and textShouldEndEditing is called, it return invalid because there is not selection, i.e., -1.

I know the objectValueForItemAt is OK in the problem controller because it is called repeatedly when I click on the down arrow on the combobox to show the entries.

The problem appears to be that objectValueForItemAt is not being called in the problem controller. I've compared both comboboxes in the story board. They are both set the same. Is there some setting I'm missing somewhere?

This is last function called in both controllers before they diverge. This version is from the problem controller:

func comboBox(_ aComboBox: NSComboBox, completedString string: String) -> String? {
    print("completed string starting. Tag: ", aComboBox.tag)
    var returnString = ""
    switch aComboBox.tag {
        case artistTableTag:
            returnString = findFirstOccurrence(table: artists.table, string: string)
        default:
            break
    }
    return returnString
}

func findFirstOccurrence(table: [[String: Any]], string: String) -> String {
    print("Starting findFirstOccurrence parm string: ", string)
    var returnString = ""
    for var dataRow in table {
        let dataString = dataRow["name"] as! String
        if dataString.commonPrefix(with: string,
                options: String.CompareOptions.caseInsensitive).lengthOfBytes(using: String.Encoding.utf8) ==
               string.lengthOfBytes(using: String.Encoding.utf8) {
            print("findFirstOccurrence dataRow: ", dataRow)
            returnString = dataRow["name"] as! String
            break
        }
    }
    print("findFirstOccurrence returning: ", returnString)
    return returnString
}

In case you're wondering about the switch statement with only one entry, the source controller has five and choose to keep consistent.


Solution

  • Found it. I had:

    func comboBox(aComboBox: NSComboBox, indexOfItemWithStringValue string: String) -> Int {
    

    instead of the correct:

    func comboBox(_ aComboBox: NSComboBox, indexOfItemWithStringValue string: String) -> Int {
    

    I've had this problem several times when copying tutorial or stackoverflow answers prior to Swift 3.0. Xcode catches a lot of out of date usage, but not this type. If your functions are not being called, check for this. I hadn't had the problem in awhile and got complacent.