How do I get a search bar to search through a dictionary and display the value in a text field when the dictionaries key is entered in the search bar? The dictionary is on a different view controller.
Replies
What is exactly your problem ?
Get access to the dictionary in the other view controller ?
If so, you could use a delegate to access data from the other controller
I have a search bar and a text view on one view controller. I have the search bar and the text view named in one file (a class). I have my dictionaries in a different file (a different class). What I want is when the user types in the search bar I want the search bar to search through all of my dictionary keys and return the value of that particular keys value in the text view. How do I do that?
What is the type of class which has the dictionary ?
Show the code to clarify.
Is it a viewController ? -> MyControllerWithDict
If so, delegation is a good way to go
Is it a completely custom class ? => MyPrivateClass
If so, you have probably created an instance of the class in the controller with the navigation bar ?
var myInstanceOfPrivateClass: MyPrivateClass
If so, simply use
myInstanceOfPrivateClass.theDictionary[theKey]
Both of the files are .swift files. Both of the classes are of type UIViewController.
Class Home: UIViewController has the search bar and text field.
Class IntroductionToComputers: UIViewController has the dictionaries.
I want the Search Bar to search through multiple dictionaries for the key typed and display the value in the text field.
import UIKit
class Home: UIViewController, UISearchBarDelegate {
@IBOutlet weak var searchBar: UISearchBar!
@IBOutlet weak var txtSearchResults: UITextView!
var isSearching: Bool = false
var searchResults: [String: String] = ["":""]
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
if searchBar.text == nil || searchBar.text == "" {
isSearching = false
view.endEditing(true)
}
else {
isSearching = true
}
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.view.endEditing(true)
}
func searchBarShouldEndEditing(_ searchBar: UISearchBar) -> Bool {
self.view.endEditing(true)
return true
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
searchBar.delegate = self
searchBar.returnKeyType = UIReturnKeyType.done
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
import UIKit
class IntroductionToComputers: UIViewController {
let favoritesDictionary = ["Color":"Red", "Car":"Ferarri", "Food":"Pizza", "Sport":"Football", "Music","Rock"]
let schoolScheduleDictionary: ["Term 1":"Math", "Term 2":"English", "Term 3":"Science", "Term 4":"Art",
"Term 5":"Gym"]
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Well, so use delegates.
Define a protocol, before IntroductionToComputers class declaration
protocol getDataProtocol {
func readDict(key: String) -> String
}
make IntroductionToComputers conform to it and implement the func
class IntroductionToComputers: UIViewController, getDataProtocol {
func readDict(key: String) -> String {
if let value = favoritesDictionary[key] { return value }
if let value = schoolScheduleDictionary[key] { return value }
return "" // nothing found
}
In Home class, create a delegate var
class Home: UIViewController, UISearchBarDelegate {
var delegate: getDataProtocol?
// in search, use the delegate to retrieve info
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
if searchBar.text == nil || searchBar.text == "" {
isSearching = false
view.endEditing(true)
}
else {
isSearching = true
let readInDictionary = delegate?.readDict(searchBar.text!)
// Use the value as you need
}
}
There is a lst thing missing: setting the delegate
For this, we need to know where you instantiate the 2 view controllers. Do you segue from IntroductionToComputers to the Home ?
In that case, in the prepare (forSegue), in IntroductionToComputers, you would have
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let destination = segue.destination as? Home {
destination.delegate = self
}
}
Or do you instantiate another way ? Please explain.
Note:
Something is not clear in your code: how do you use the dictionaries in IntroductionToComputers ? I do not see them used anywhere.
Another approach would be to define a model
class DataDict {
let favoritesDictionary = ["Color":"Red", "Car":"Ferarri", "Food":"Pizza", "Sport":"Football", "Music","Rock"]
let schoolScheduleDictionary: ["Term 1":"Math", "Term 2":"English", "Term 3":"Science", "Term 4":"Art",
"Term 5":"Gym"]
func readDict(key: String) -> String {
if let value = favoritesDictionary[key] { return value }
if let value = schoolScheduleDictionary[key] { return value }
return "" // nothing found
}
}
Then in Home class, create an instance of the model
class Home: UIViewController, UISearchBarDelegate {
var dataModel: DataDict?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
searchBar.delegate = self
searchBar.returnKeyType = UIReturnKeyType.done
dataModel = DataDict()
}
You can now access in the search
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
if searchBar.text == nil || searchBar.text == "" {
isSearching = false
view.endEditing(true)
}
else {
isSearching = true
let readInDictionary = dataModel.readDict(searchBar.text!)
// Use the value as you need
}
}