Reputation: 133
I have tableview with alphabetic sections from my database and I want to add search bar but i can't figure it out how to filter the data and implement it in the tableview. My database store inside two structs:
one struct holding all the data.
second struct gets the first letter for the sections and the first struct as array.
My structs:
struct SentenceInfo { // First struct (holds all the data)
let name: String
let detail: String
let sentence: String
init(name: String, detail: String, sentence: String) {
self.name = name
self.detail = detail
self.sentence = sentence
}
}
struct SentenceNameSection { // Second struct (first letter and array of the first struct)
var firstLetter: String
var crimes: [SentenceInfo]
init(title: String, objects: [SentenceInfo]) {
firstLetter = title
crimes = objects
}
}
My tableView:
var sections : [SentenceNameSection]!
var crimeData = [SentenceNameSection]()
var filteredData = [SentenceNameSection]()
var shouldShowSearchResults = false
var searchController: UISearchController!
func updateSearchResults(for searchController: UISearchController) {
let searchString = searchController.searchBar.text
filteredData = crimeData.filter({ (crime) -> Bool in
let crimeMatch: String = crime // Error about types
return ((crimeMatch.range(of: searchString!) != nil))
})
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: sentenceTableViewCell = tableView.dequeueReusableCell(withIdentifier: cellIdentifer, for: indexPath) as! sentenceTableViewCell
let crime: SentenceInfo = sections[indexPath.section].crimes[indexPath.row]
cell.nameLabel.text = crime.name
cell.detailLabel.text = crime.detail
cell.sentenceLabel.text = crime.sentence
return cell
}
Upvotes: 4
Views: 2289
Reputation: 355
For Swift 3 , below is the sample code
Struct BookDetails{
var title:String?
var author:String?
}
var filteredSearch:[BookDetails] = []
filteredSearch = self.bookDetails.filter { (data) -> Bool in
return data.title?.range(of: searchText, options: String.CompareOptions.caseInsensitive) != nil || data.author?.range(of: searchText, options: String.CompareOptions.caseInsensitive) != nil
}
Upvotes: 0
Reputation: 285082
First of all crimeData
contains SentenceNameSection
which cannot be compared to String
Apart from that to filter the data source array including sections you have to use a repeat loop and create new SentenceNameSection
items
This code searches for all three properties in the SentenceInfo
struct
let searchString = searchController.searchBar.text!
filteredData.removeAll() // is mandatory to empty the filtered array
for section in crimeData {
let filteredContent = section.crimes.filter { $0.name.range(of: searchString) != nil
|| $0.detail.range(of: searchString) != nil
|| $0.sentence.range(of: searchString) != nil
}
if !filteredContent.isEmpty {
filteredData.append(SentenceNameSection(title: section.firstLetter, objects: filteredContent))
}
}
Note: Of course you have to handle the search
case in all appropriate table view data source and delegate methods.
Upvotes: 2