Implementing Toolbar Search item

I am developing an app that has a tableview and a search view in the view controller and I have this feature working fine. However, I would like to move this search to use a toolbar search item. So, I was looking in the Coca programming for OS X and did not find any section dealing with implementing a search feature in the toolbar.
So, can anyone direct me to any tutorials/books that would help with this?

Thanks

Did you try adding a Toolbar to the Window, and a Search Field to the toolbar?
Toolbar

Yes, I did add a Search Field to the toolbar, but I don’t see a way to create an @IBOutlet in the view controller as I did with the search field in the window. I think the protocol for implementing the search field in the toolbar will require several steps.

The Coca programming for OS X had a section on NSColor protocol and I was looking for a similar tutorial for implementing a search field in the toolbar.

Try accessing the window from the view controller, and then access the toolbar. To do this, you will have to create a custom window.

//  MyWindow.swift

import Cocoa

class MyWindow: NSWindow {
    @IBOutlet var toolBar: NSToolbar!
}
//  ViewController.swift

import Cocoa

class ViewController: NSViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    }

    override var representedObject: Any? {
        didSet {
        // Update the view, if already loaded.
        }
    }

    override func viewWillAppear() {
        if let window = self.view.window as? MyWindow {
            print ("\(window.toolBar.items)")
        }
    }
}

Thanks for your answer…

I mostly follow your answer however I don’t see how to connect:

import Cocoa

class MyWindow: NSWindow {
    @IBOutlet var toolBar: NSToolbar!
}

the IBOutlet above to the toolbar in IB. What am I missing.

Make sure that the window is properly configured in IB:

Its Custom Class attribute is set to the custom class (MyWindow) with the Toolbar outlet.

Thanks for the help. That was easy once you supplied the answer… Back to reading Cocoa programming for OS X.

However, I thought I could figure out how to get a hold of the search field it the toolbar. I tried the following code:

  override func viewWillAppear() {
          if let window = self.view.window as? CustWindow {
            print ("\(window.toolBar.identifier)")
            let toolBarItem = NSToolbar(identifier: window.toolBar.identifier)
            custSearchField = toolBarItem.??????
            print(toolBarItem)
          }
      }

but I did not see how to assign the search field in the toolbar to my variable custSearchField or expose the field to my view controller class. Please advise…

It turns out that there is no need to create a custom window in order to access the toolbar; the standard window already comes with a toolbar property.

The example below assumes that there is only one item in the toolbar: the Search Field.

//  ViewController.swift

import Cocoa

class ViewController: NSViewController {

    override func viewWillAppear() {
        
        guard let toolbar = self.view.window?.toolbar else {
            return
        }
                
        guard let searchFieldToolbarItem = toolbar.items.first else {
            return
        }

        guard let searchField = searchFieldToolbarItem.view as? NSSearchField else {
            return
        }
                
        searchField.target = self
        searchField.action = #selector (procSearchFieldInput (sender:))
    }
    
    @objc func procSearchFieldInput (sender:NSSearchField) {
        print ("\(#function): \(sender.stringValue)")
    }
}

Thanks got it all working…I like this solution much better…

I tried to use this code in another custom view controller and got different results.

I have the following code in two custom view controllers.

// ToolBar Search override func viewWillAppear() {
guard let toolbar = self.view.window?.toolbar else {
    return
}
guard let searchFieldToolbarItem = toolbar.items.last else {
    return
}
custSearchField = (searchFieldToolbarItem.view as? NSSearchField)!
createMenuForSearchField()
custSearchField.target = self
custSearchField.action = #selector (custSearch (sender:))
}

Below is what I see with the debugger for the instance that works.

One instance shows baseNSSearchToolbarItem and then a baseNSToolbarItem before it gets to the baseNSObject while the other one starts with the baseNSObject. Why is this? Any ideas how to fix?

Here is the debugger that does not work

I got this working. The problem was resolved by adding a “search item” object in the toolbar instead of a “search Toolbar item” object.