Search bar in Swift not searching with a PHP file - ios

I have no errors in my code but there's definitely something missing. Also there when I press done in the keyboard nothing happens. It might have to do with the search bar function or the table view function. I also have a Search.swift file and I will add it. Any suggestions would be very helpful, I feel really stuck.
SearchBarViewController:
let url = URL(string: "http://127.0.0.1/musicfiles/search.php")
var filteredData = [String]()
var shouldShowSearchResults = false
var search: [Search] = []
var filePath = "http://127.0.0.1/musicfiles/search.php"
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
searchBar.delegate = self
searchBar.returnKeyType = UIReturnKeyType.done
let task = URLSession.shared.dataTask(with: url!) { (data, snapshot, error) in
let retrievedList = String(data: data!, encoding: String.Encoding.utf8)
print(retrievedList!)
self.parseSongs(data: retrievedList!)
}
task.resume()
}
func parseSongs (data: String) {
if (data.contains("*")) {
let dataArray = (data as String).split(separator: "*").map(String.init)
for item in dataArray {
let itemData = item.split(separator: ",").map(String.init)
let searchSong = Search(songname: itemData[0])
search.append(searchSong!)
for s in search {
print(s.searchSongName())
}
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return search.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! DataCell
let song = search[indexPath.row].searchSongName()
cell.congigureCell(text: song)
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let searchSong = search[indexPath.row].searchSongName()
let fileURLString = "\(filePath)\(searchSong)"
print(fileURLString)
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
if searchBar.text == nil || searchBar.text == "" {
shouldShowSearchResults = false
view.endEditing(true)
filteredData.removeAll()
} else {
shouldShowSearchResults = true
filteredData = search.filter({ (songName) -> Bool in
songName.searchSongName().range(of: searchText) != nil
})
.map { $0.songname }
}
tableView.reloadData()
}

You are loading your data into an array called search.
When you filter your data, you are placing the filtered data into an array called filteredData.
Your tableview always shows the contents of search, so you never see the results of your filtering.
You could check whether filteredData is empty and then return data from that array or search in numberOfRows and cellForRow. Personally I would always use filteredData and make sure that it holds the contents of search when the filter string is empty.
var filteredData = [Search]()
func parseSongs (data: String) {
if (data.contains("*")) {
let dataArray = (data as String).split(separator: "*").map(String.init)
for item in dataArray {
let itemData = item.split(separator: ",").map(String.init)
let searchSong = Search(songname: itemData[0])
search.append(searchSong!)
for s in search {
print(s.searchSongName())
}
self.filterData = self.search
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return filteredData.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! DataCell
let song = filteredData[indexPath.row].searchSongName()
cell.congigureCell(text: song)
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let searchSong = filteredData[indexPath.row].searchSongName()
let fileURLString = "\(filePath)\(searchSong)"
print(fileURLString)
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
if (searchBar.text ?? "").isEmpty {
view.endEditing(true)
filteredData = search
} else {
filteredData = search.filter({ (songName) -> Bool in
songName.searchSongName().range(of: searchText) != nil
})
}
tableView.reloadData()
}

Related

Swift SearchBar inTableView doesn't show the correct Data in the filtered rows

My app is using Firebase Realtime Database to store information of each user. The tableView works fine. I added a searchBar and when I type letters in the searchBar, I can see that the amount of rows presented in the tableView is equal to the amount of users which contain these letters in their names. The problem is that the rows presented in the tableview (after typing letters in the search bar), contain the information of the first user till x user (x = amount of users which contain these letters in their names).
import UIKit
import FirebaseDatabase
import Firebase
class VideoListScreen: UIViewController {
#IBOutlet weak var tableView: UITableView!
var blogPost: [BlogPost] = []
var searchBlogPost = [BlogPost]()
var searching = false
override func viewDidLoad() {
super.viewDidLoad()
blogPost = []
createArray()
tableView.delegate = self
tableView.dataSource = self
}
func createArray() {
let ref = Database.database().reference().child("Users")
ref.observe(.childAdded, with: { (snapshot) in
if let postDict = snapshot.value as? [String : String] {
let post = BlogPost(name:postDict["name"] ?? "" , gaf: postDict["gaf"] ?? "", place: postDict["place"] ?? "", phone: postDict["phone"] ?? "", notes: postDict["notes"] ?? "", elsertext: postDict["elsertext"] ?? "")
self.blogPost.append(post)
self.tableView.reloadData()
}
})
}
}
extension VideoListScreen: UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if searching{
return searchBlogPost.count
}else{
return blogPost.count
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let blogp = blogPost[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: "Tavla") as! Tavla
if searching{
cell.setBLogPost(blogPost: searchBlogPost[indexPath.row])
}
else{
cell.setBLogPost(blogPost: blogPost[indexPath.row])
}
cell.setBLogPost(blogPost: blogp)
return cell
}
}
extension VideoListScreen: UISearchBarDelegate {
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
searchBlogPost = blogPost.filter({$0.name.prefix(searchText.count) == searchText})
searching = true
tableView.reloadData()
}
}
I Believe the problem is in the if and else statments in this function:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let blogp = blogPost[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: "Tavla") as! Tavla
if searching{
cell.setBLogPost(blogPost: searchBlogPost[indexPath.row])
}
else{
cell.setBLogPost(blogPost: blogPost[indexPath.row])
}
cell.setBLogPost(blogPost: blogp)
return cell
}
You have extra cell.setBLogPost(blogPost: blogp) in your delegate methode
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let blogp = blogPost[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: "Tavla") as! Tavla
if searching{
cell.setBLogPost(blogPost: searchBlogPost[indexPath.row])
}
else{
cell.setBLogPost(blogPost: blogPost[indexPath.row])
}
return cell
}
I think this will solve your problem and you can use
import UIKit
import FirebaseDatabase
import Firebase
class VideoListScreen: UIViewController {
#IBOutlet weak var tableView: UITableView!
var blogPost: [BlogPost] = []
var searchBlogPost = [BlogPost]()
override func viewDidLoad() {
super.viewDidLoad()
blogPost = []
createArray()
tableView.delegate = self
tableView.dataSource = self
}
func createArray() {
let ref = Database.database().reference().child("Users")
ref.observe(.childAdded, with: { (snapshot) in
if let postDict = snapshot.value as? [String : String] {
let post = BlogPost(name:postDict["name"] ?? "" , gaf: postDict["gaf"] ?? "", place: postDict["place"] ?? "", phone: postDict["phone"] ?? "", notes: postDict["notes"] ?? "", elsertext: postDict["elsertext"] ?? "")
self.blogPost.append(post)
self.searchBlogPost = self.blogPost
self.tableView.reloadData()
}
})
}
}
extension VideoListScreen: UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return searchBlogPost.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let blogp = searchBlogPost[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: "Tavla") as! Tavla
cell.setBLogPost(blogPost: blogp)
return cell
}
}
extension VideoListScreen: UISearchBarDelegate {
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
if ((searchText.trimmingCharacters(in: .whitespaces).isEmpty) {
searchBlogPost = blogPost
} else {
searchBlogPost = blogPost.filter({$0.name.prefix(searchText.count) == searchText})
}
tableView.reloadData()
}
}
I hope this will helps.

Searchbar filtering issue

Im new to the swift, I am trying to filter name from an array using the search bar in console am getting what I entered in the search bar but filtering with predicate im not getting filtered name...please can anyone help in this issue
var caseListOfBooker:[CaseDetails]=[]
var searchString:String=""
var filteredString = [String]()
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
print("searchText \(searchText)")
searchString = searchText
updateSearchResults()
tableview.reloadData()
}
func updateSearchResults(){
filteredString.removeAll(keepingCapacity: false)
let searchPredicate = NSPredicate(format: "SELF CONTAINS[c] %#", searchString)
let array = self.caseListOfBooker.filter{$0.person_of_interest.contains(searchString)}
print(array)
if let list=array as? [String]{
filteredString=list
}
print(filteredString)
tableview.reloadData()
}
extension SearchPOIVC : UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if filteredString != []{
return filteredString.count
}
else
{
if searchString != "[]" {
return caseListOfBooker.count
}else {
return 0
}
}
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 80.00
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell:POIProfileDetailsCell = tableview.dequeueReusableCell(withIdentifier: "POIProfileDetailsCell", for: indexPath) as! POIProfileDetailsCell
if filteredString != []{
cell.poiName.text = filteredString[indexPath.row]
return cell
}else{
if searchString != "[]"{
cell.poiName.text = self.caseListOfBooker[indexPath.row].person_of_interest
}
return cell
}
}
The most efficient way to filter custom classes is to use the same type for the data source array and the filtered array
var caseListOfBooker = [CaseDetails]()
var filteredBooker = [CaseDetails]()
Add a property isFiltering which is set to true when the search text is not empty
var isFiltering = false
and delete searchString and filteredString
var searchString:String=""
var filteredString = [String]()
In updateSearchResults filter the data source array (with native Swift functions), set isFiltering accordingly and reload the table view
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
print("searchText \(searchText)")
updateSearchResults(searchText: searchText)
}
func updateSearchResults(searchText: String) {
if searchText.isEmpty {
filteredBooker.removeAll()
isFiltering = false
} else {
filteredBooker = caseListOfBooker.filter{$0.person_of_interest.range(of: searchText, options: .caseInsensitive) != nil }
isFiltering = true
}
tableview.reloadData()
}
In the table view data source methods display the data depending on isFiltering
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return isFiltering ? filteredBooker.count : caseListOfBooker.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableview.dequeueReusableCell(withIdentifier: "POIProfileDetailsCell", for: indexPath) as! POIProfileDetailsCell
let booker = isFiltering ? filteredBooker[indexPath.row] : caseListOfBooker[indexPath.row]
cell.poiName.text = booker.person_of_interest
}
let array = self.caseListOfBooker.filter{$0.person_of_interest.contains(searchString)}
You are getting array of CaseDetails objects and trying to cast to array of String
It fails. You need to get string values from the CaseDetails object and join them
Use
filteredString = array.map { $0.person_of_interest }
Or
for caseDetail in array {
filteredString.append(caseDetail.person_of_interest)
}
Instead of
if let list = array as? [String]{
filteredString=list
}
var searchPredicate = NSPredicate()
searchPredicate = NSPredicate(format: "self CONTAINS[C] %#", your_searching_text)
let Final_Search_array = (Your_Array).filtered(using: searchPredicate)

SearchBar is not returning my search into Contacts

I'm currently working with Xcode 10 and Swift 4.2 and I was trying to search to my list of contacts using a SearchBar, all done except that the SearchBar is returning index out of bounds. Here is my code:
#IBOutlet weak var searchBar: UISearchBar!
var contactList: [CNContact]!
var inSearchMode = false
var filteredData = [CNContact]()
override func viewDidLoad() {
super.viewDidLoad()
searchBar.delegate = self
searchBar.returnKeyType = UIReturnKeyType.done
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let store = CNContactStore()
store.requestAccess(for: .contacts, completionHandler: { (success, error) in
if success {
let keys = CNContactViewController.descriptorForRequiredKeys()
let request = CNContactFetchRequest(keysToFetch: [keys])
do {
self.contactList = []
try store.enumerateContacts(with: request, usingBlock: { (contact, status) in
self.contactList.append(contact)
})
} catch {
print("Error")
}
OperationQueue.main.addOperation({
self.tableView.reloadData()
})
}
})
}
Last night I made search func here on stack and all is fine except for that error that throws when running the app. How can I solve it?
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if contactList != nil {
return contactList.count
}
if inSearchMode {
return filteredData.count
}
return 0
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "contactCell", for: indexPath)
let contact: CNContact!
contact = contactList[indexPath.row]
cell.textLabel?.text = "\(contact.givenName) \(contact.familyName)"
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let contact = contactList[indexPath.row]
let controller = CNContactViewController(for: contact)
navigationController?.pushViewController(controller, animated: true)
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
if searchBar.text == nil || searchBar.text == "" {
inSearchMode = false
view.endEditing(true)
tableView.reloadData()
} else{
inSearchMode = true
filteredData = contactList.filter {
$0.givenName.range(of: searchBar.text!, options: [.caseInsensitive, .diacriticInsensitive ]) != nil ||
$0.familyName.range(of: searchBar.text!, options: [.caseInsensitive, .diacriticInsensitive ]) != nil
}
tableView.reloadData()
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "contactCell", for: indexPath)
let contact: CNContact!
if inSearchMode {
contact = filteredData[indexPath.row]
} else {
contact = contactList[indexPath.row]
}
cell.textLabel?.text = "\(contact.givenName) \(contact.familyName)"
return cell
}
you should check if you are in search mode or not in cellForRow to fetch correctly
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if inSearchMode {
return filteredData.count
}
if contactList != nil {
return contactList.count
}
return 0
}
when you call reloadData() -numberOfRows -CellForRow are recalling also

Swift 3/4: SearchBar not filtering results properly in TableView

I have a popup with searchBar at the top and TableView below it. TableView is populated by dynamic data. I have a custom tableViewCell, with a label for names and a checkBox(M13CheckBox Library) to select a name.
Now, when I search for a name, Firstly the tableView is not loaded as the user types a name in the search bar. For eg, Suppose there are persons named "Mary", "Mackenzie", "Margaret" and "Mallory". I want to search for "Margaret", so as I start typing "Mar" in searchBar, then "Mary" and "Margaret" are filtered properly in tableView, but when I go back i.e "Ma", then it should show all the 4 names, since "Ma" is present in the list, But the tableView does not show anything.
So tableView should always reload as user types in searchBar if the letters are contained in the names. Please help me sort this issue. Since it is a popup I am passing data to tableView from another VC, by notification.
Here is my code for search VC:
class ParticipantsListVC: UIViewController, UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate{
public static var participantNameArray:[String] = [String]() //global var
var viewController: ViewController!
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
searchParticipantFilter.delegate = self
viewController = ViewController()
let notificationName = NSNotification.Name("reloadList")
NotificationCenter.default.addObserver(forName: notificationName, object: nil, queue: OperationQueue.main) { (notifObject) in
self.tableView.reloadData()
}
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText:String) {
if searchText == "" {
ParticipantsListVC.participantNameArray.removeAll()
viewController.getParticipantList() // func to get list from sever
}else{
ParticipantsListVC.participantNameArray = ParticipantsListVC.participantNameArray.filter({(name) -> Bool in
return name.lowercased().contains(searchText.lowercased())
})
}
self.tableView.reloadData()
}
}
Also if I select a name, then checkBox is selected in front of that name.But when I click on cancel(X) in searchBar, then always the first cell in tableView is shown selected and not the name that I had selected. I don't know why always the first cell gets selected, after selecting name from filtered list.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! ParticipantListCell
let dict = ParticipantsListVC.participantNameArray[indexPath.row]
cell.participantNameLabel.text = dict
if selectedIndexPaths.contains(indexPath) {
cell.selectedParticipantCB.setCheckState(.checked, animated: true)
}else{
cell.selectedParticipantCB.setCheckState(.unchecked, animated: true)
}
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// Since any random cell was getting selected on scrolling So I added this code.
tableView.deselectRow(at: indexPath, animated: true)
if selectedIndexPaths.contains(indexPath) {
selectedIndexPaths.removeObject(object: indexPath)
}else{
selectedIndexPaths.append(indexPath)
}
tableView.reloadData()
}
I don't want to use searchBar in headerView or another tableView to show filtered list. Please much appreciated.Thank you.
You need to create another array to hold the backup of data array.
var arrParticipantList = [String]()
var arrParticipantListBackup = [String]()
override func viewDidLoad() {
super.viewDidLoad()
self.searchBar.delegate = self
self.tblParticipantList.delegate = self
self.tblParticipantList.dataSource = self
self.arrParticipantList = ["Mary", "Mackenzie", "Margaret", "Mallory","Molly"]
self.arrParticipantListBackup = self.arrParticipantList
}
Code to search for search string, refill array and reload tableview
extension ViewController: UISearchBarDelegate {
func searchBar(_ searchBar: UISearchBar, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
var searchText = searchBar.text! + text
if range.length > 0 {
if range.location == 0 {
self.arrParticipantList = self.arrParticipantListBackup
self.tblParticipantList.reloadData()
return true
}
searchText = String(searchText.dropLast(range.length))
}
self.arrParticipantList = self.arrParticipantListBackup.filter({$0.lowercased().hasPrefix(searchText.lowercased())})
self.tblParticipantList.reloadData()
return true
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
self.searchBar.text = ""
self.searchBar.resignFirstResponder()
self.arrParticipantList = self.arrParticipantListBackup
self.tblParticipantList.reloadData()
}
}
Code for tableview
extension ViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.arrParticipantList.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell")
cell?.textLabel?.text = self.arrParticipantList[indexPath.row]
return cell!
}
}
Hope this solves your issue.
struct namelist {
var searchname: NSString
}
var searchActive = Bool()
var newSearchArray = [namelist]()
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return searchActive ? newSearchArray.count : nameOldArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let Cell:SearchTableViewCell! = tableView.dequeueReusableCell(withIdentifier: "Cell") as! SearchTableViewCell
Cell.selectionStyle = .none
if (searchActive == true) {
if ( newSearchArray.count > 0) {
var para = NSMutableAttributedString()
para = NSMutableAttributedString(string:(newSearchArray[indexPath.row].searchname) as String)
do {
let regex = try NSRegularExpression(pattern: searchText, options: NSRegularExpression.Options.caseInsensitive )
let nsstr = newSearchArray[indexPath.row].searchname
text = nsstr as String
let all = NSRange(location: 0, length: nsstr.length)
var matches : [String] = [String]()
regex.enumerateMatches(in: text, options: NSRegularExpression.MatchingOptions(rawValue: 0), range: all) {
(result : NSTextCheckingResult?, _, _) in
if let r = result {
let results = nsstr.substring(with: r.range) as String
matches.append(results)
let substringrange = result!.rangeAt(0)
para.addAttribute(NSForegroundColorAttributeName, value:UIColor.init(red: 237/255.0, green: 60/255.0, blue: 58/255.0, alpha: 1.0), range: substringrange)
Cell.namelbl.attributedText = para
}
}
} catch {
}
}
}
else {
Cell.namelbl.text = self.searchname[indexPath.row] as? String
}
return Cell
}
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
searchArray.removeAllObjects()
newSearchArray.removeAll()
if Search.text != nil {
for i in 0 ..< searchname.count {
searchText = Search.text!
text = ((searchname.object(at: i))) as! String
if text.lowercased().contains(searchText.lowercased()) {
let elm = namelist(searchname: text as NSString)
self.newSearchArray.append(elm)
}
}
}
searchActive = !newSearchArray.isEmpty
searchBar.resignFirstResponder()
yourTableName.reloadData()
}

Filter result(s) in array of class (Swift 3)

In Class
class Objects {
var number: Int!
var name: String!
init(number: Int, name: String) {
self.number = number
self.name = name
}
}
In viewController
var allObjects = [Objects]()
var inSearchMode = false
#IBOutlet weak var searchBar: UISearchBar!
override func viewDidLoad() {
super.viewDidLoad()
searchBar.delegate = self
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! Cell
if inSearchMode {
let fill: Objects!
fill = filteredObject[indexPath.row]
cell.configureCell(fill)
} else {
let fill: Objects!
fill = allObjects[indexPath.row]
cell.configureCell(fill)
return cell
}
}
return UITableViewCell()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if inSearchMode {
return filteredObject.count
}
return allObjects.count
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
if searchBar.text == nil || searchBar.text == "" {
inSearchMode = false
tableView.reloadData()
view.endEditing(true)
} else {
inSearchMode = true
var lowerCase = Int(searchBar.text!)
filteredObject = allObjects.filter({$0.number == lowerCase})
tableView.reloadData()
print(filteredObject)
}
}
I would like to have a search bar that filters and shows only one result that contains the number we are looking for. I thought about using contains and put the number we input from the search bar.
I manage to get one object into the filteredObject, but it won't show up in the tableView
Look carefully at this part of your code:
if inSearchMode {
let fill: Objects!
fill = filteredObject[indexPath.row]
cell.configureCell(fill)
} else {
let fill: Objects!
fill = allObjects[indexPath.row]
cell.configureCell(fill)
return cell
}
You did not return a cell when you are in search mode, that is why you do not see anything when searching.
I would use a computed property to drive the tableview; This property is either all the objects or the filtered object(s):
var allObjects = [Objects]()
var filteredObjects: [Objects]?
var objects: [Objects] = {
return filteredObjects ?? allObjects
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.objects.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! Cell
let fill = self.objects[indexPath.row]
cell.configureCell(fill)
return cell
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
if searchBar.text == nil || searchBar.text == "" {
self.filteredObjects = nil
} else {
var lowerCase = Int(searchBar.text!)
self.filteredObjects = allObjects.filter({$0.number == lowerCase})
}
tableView.reloadData()
}

Resources