Reputation: 63
I am using an array variable called sections as the table view has collapsable sections:
var sections = [
// TESTING CODE FOR SECTIONS
Section(sec: "One",
subSec: ["A", "B", "C", "D", "E"],
expanded: false),
Section(sec: "Two",
subSec: ["A", "B", "C", "D", "E"],
expanded: false),
Section(sec: "Three",
subSec: ["A", "B", "C", "D", "E"],
expanded: false),
I am trying to use UISearchController to make the table view searchable. Here is what I have tried so far but its not working:
func filterContentForSearchText(_ searchText: String, scope: String = "All") {
filtered = sections.filter({( section : Section) -> Bool in
return section.subSec.name.lowercased().contains(searchText.lowercased())
})
tableView.reloadData()
}
I understand how the function works but cannot seem to get it to work with my subSec in the variable.
//SEARCH
var filteredSections: [String]?
let searchController = UISearchController(searchResultsController: nil)
override func viewDidLoad() {
super.viewDidLoad()
//SEARCH
filteredSections = sections
searchController.searchResultsUpdater = self
searchController.hidesNavigationBarDuringPresentation = false
searchController.dimsBackgroundDuringPresentation = false
tableView.tableHeaderView = searchController.searchBar
}
I get errors such as 'cannot assign value of type '[Section]' to type '[String]?' I understand why, but I don't know how to resolve this.
Section definition:
struct Section {
var sec: String!
var subSec: [String]! // [ ] = Array of Strings
var expanded: Bool!
init(sec: String, subSec: [String], expanded: Bool) {
self.sec = sec
self.subSec = subSec
self.expanded = expanded
}
}
Upvotes: 1
Views: 60
Reputation: 54706
filteredSections
is an array of Strings and you are trying to assign the output of a filter function called on an array of Section
s, which return an array of Section
s, so it obviously won't work.
If you want to return String
s as a result of filtering the array of Section
s, you need to combine filter
and map
, which can be done with a single flatMap
.
The ternary operator inside the flatMap checks the same condition as your filter did, but it returns section.subSec.name
if the condition evaluates to true and nil
otherwise, which the flatMap
simply ignores, hence the output array will only contain the matching subsection names.
func filterContentForSearchText(_ searchText: String, scope: String = "All") {
filtered = sections.flatMap{ return $0.subSec.name.lowercased().contains(searchText.lowercased()) ? searchText : nil }
tableView.reloadData()
}
Since you didn't include the definition of Section
in your code, I couldn't test the function, but if subSec.name
is a String
, it will work just fine.
Upvotes: 1