davidev
davidev

Reputation: 8517

SwiftUI Mac OSX SearchBar element

I am currently developing a app in SwiftUI for MacOSX. I am having a custom List View with many rows. I want a SearchBar to filter my rows.

Coming from Objective C, I know there was a SearchBar and SearchBar Controller. I just would need a SearchBar with the default Mac OS X Search Bar design. However, I didn't found anything.

There was a answer on Stackoverflow, which dealted with the same problem but for iOS. But that is not convertible to Mac OS X.

Currently I am using a regular TextField and wrote my own filter script, which worked fine. However, I want to SearchField UI as Apple uses it. Is that possible?

Is there any chance to use AppKit to achieve that?

That's what I want to achieve:

enter image description here

Upvotes: 3

Views: 1695

Answers (2)

davidev
davidev

Reputation: 8517

Here is my solution that I am now using:

struct FirstResponderNSSearchFieldRepresentable: NSViewControllerRepresentable {

    @Binding var text: String

      func makeNSViewController(
        context: NSViewControllerRepresentableContext<FirstResponderNSSearchFieldRepresentable>
      ) -> FirstResponderNSSearchFieldController {
        return FirstResponderNSSearchFieldController(text: $text)
      }

      func updateNSViewController(
        _ nsViewController: FirstResponderNSSearchFieldController,
        context: NSViewControllerRepresentableContext<FirstResponderNSSearchFieldRepresentable>
      ) {
      }
}

And here the NSViewController

class FirstResponderNSSearchFieldController: NSViewController {

  @Binding var text: String
  var isFirstResponder : Bool = true

    init(text: Binding<String>, isFirstResponder : Bool = true) {
    self._text = text
    super.init(nibName: nil, bundle: nil)
  }

  required init?(coder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
  }

  override func loadView() {
    let searchField = NSSearchField()
    searchField.delegate = self
    
    self.view = searchField
  }

  override func viewDidAppear() {
    self.view.window?.makeFirstResponder(self.view)
  }
}


extension FirstResponderNSSearchFieldController: NSSearchFieldDelegate {

  func controlTextDidChange(_ obj: Notification) {
    if let textField = obj.object as? NSTextField {
      self.text = textField.stringValue
    }
  }
}

Upvotes: 1

Procrastin8
Procrastin8

Reputation: 4503

Your best bet is to wrap an NSSearchField in an NSViewRepresentable.

Upvotes: 2

Related Questions