How to make UITextField behave like a UISearchBar in Swift?
Your primary question seems to be asking how to implement a class that works just like the UISearchBar. That would be a huge undertaking!
However, in your notes you just ask how to react to the search button getting tapped.
Add an IBAction and a second array to your view controller. Call the second array something like "foundItems". Connect the IBAction to the search button. When the action is called, read the text out of the text field and filter the items based on that text. Put the items that conform to the filter in the foundItems array, then call reloadData() on your table view.
In your table view data source methods, check to see if foundItems is not nil. If it isn't, then display them instead of your main items array.
You will also need some sort of cancel button. In that button's action, nil out the foundItems array and call reloadData() on your table view.
Xcode 9.2 / Swift 4 -- Working Code
@IBOutlet var tfSearchWorker: UITextField!
@IBOutlet var tblView: UITableView!
var AllData :Array<Dictionary<String,String>> = []
var SearchedData:Array<Dictionary<String,String>> = []
@ViewDidLoad
AllData = [["pic":"list0.jpg", "name":"Angel Mark", "msg":"Hi there, I would like read your...", "time":"just now", "unread":"12"],
["pic":"list1.jpg", "name":"John Doe", "msg":"I would prefer reading on night...", "time":"56 second ago", "unread":"2"],
["pic":"list2.jpg", "name":"Krishta Hide", "msg":"Okey Great..!", "time":"2m ago", "unread":"0"],
["pic":"list3.jpg", "name":"Keithy Pamela", "msg":"I am waiting there", "time":"5h ago", "unread":"0"]
]
self.SearchedData = self.AllData
self.tfSearchWorker.addTarget(self, action: #selector(searchWorkersAsPerText(_ :)), for: .editingChanged)
@Function
@objc func searchWorkersAsPerText(_ textfield:UITextField) {
self.SearchedData.removeAll()
if textfield.text?.count != 0 {
for dicData in self.AllData {
let isMachingWorker : NSString = (dicData.name!) as NSString
let range = isMachingWorker.lowercased.range(of: textfield.text!, options: NSString.CompareOptions.caseInsensitive, range: nil, locale: nil)
if range != nil {
SearchedData.append(dicData)
}
}
} else {
self.SearchedData = self.AllData
}
self.tblView.reloadData()
}
@UITableView
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.SearchedData.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "ListCell") as! ListCell
var Data:Dictionary<String,String> = SearchedData[indexPath.row]
cell.Pic.image=UIImage(named: Data["pic"]!)
cell.Name.text = Data["name"]
cell.Msg.text = Data["msg"]
cell.Time.text = Data["time"]
cell.selectionStyle = .none
return cell
}
Create uitextfield object:
@IBOutlet var SearchTxt: UITextField!
var search:String=""
@IBOutlet var ListTable: UITableView!
var AllData:Array<Dictionary<String,String>> = []
var SearchData:Array<Dictionary<String,String>> = []
Viewdidload:
override func viewDidLoad()
{
super.viewDidLoad()
AllData = [["pic":"list0.jpg", "name":"Angel Mark", "msg":"Hi there, I would like read your...", "time":"just now", "unread":"12"],
["pic":"list1.jpg", "name":"John Doe", "msg":"I would prefer reading on night...", "time":"56 second ago", "unread":"2"],
["pic":"list2.jpg", "name":"Krishta Hide", "msg":"Okey Great..!", "time":"2m ago", "unread":"0"],
["pic":"list3.jpg", "name":"Keithy Pamela", "msg":"I am waiting there", "time":"5h ago", "unread":"0"]
]
SearchData=AllData
}
Search in textfield delegate method:
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
{
if string.isEmpty
{
search = String(search.characters.dropLast())
}
else
{
search=textField.text!+string
}
print(search)
let predicate=NSPredicate(format: "SELF.name CONTAINS[cd] %@", search)
let arr=(AllData as NSArray).filtered(using: predicate)
if arr.count > 0
{
SearchData.removeAll(keepingCapacity: true)
SearchData=arr as! Array<Dictionary<String,String>>
}
else
{
SearchData=AllData
}
ListTable.reloadData()
return true
}
Search data display in tableview :
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return SearchData.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "ListCell") as! ListCell
var Data:Dictionary<String,String> = SearchData[indexPath.row]
cell.Pic.image=UIImage(named: Data["pic"]!)
cell.Name.text = Data["name"]
cell.Msg.text = Data["msg"]
cell.Time.text = Data["time"]
cell.selectionStyle = .none
return cell
}
With the help of @Daniel T. I managed to solve the problem with the following code:
func textFieldShouldReturn(textField: UITextField) -> Bool {
isFiltered = true
searchResults = prods.filter({(coisas:String) -> Bool in
let stringMatch = coisas.rangeOfString(textField.text)
return stringMatch != nil
})
println(searchResults.description)
textField.resignFirstResponder()
table.reloadData()
return true
}
Thanks @Daniel T.