I am setting up a UISearchBar for my mathematics app. The search bar is supposed to search through an array allItems
to find what the user is searching. The array allItems
uses a struct called Headline
to define an item ID and an item Title. When I try to fill out the UISearchBar textDidChange func, I get this error: Cannot assign value of type '[Headline]' to type '[String?]'
My code is attached below:
For the array and struct setup-
struct Headline {
var id: Double
var title: String
}
let allItems = invest+geoArea+geoVolume+geoSA+geoLSA+advPythag+advPhysics+advConv+advOther
The arrays that makes up allItems
are using the struct Headline
For the UISearchBar-
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
searchCalc = allItems.filter({$0.title.lowercased().prefix(searchText.count) == searchText.lowercased()})
isSearching = true
tableView.reloadData()
}
Other Helpful Code:
var searchCalc = [String?]()
The isSearching Bool is just to help the app know when the user is actively searching for something
Also, searchCalc is the variable used to store what the user is currently searching. It is supposed to be string so that the app can filter out array items based on what the user is typing.
And this code block will be long, but it might help make more sense. Below is the code used to create all of the arrays inside allItems
-
let invest = [
Headline(id: 1.01, title: "Simple Interest"),
Headline(id: 1.02, title: "Compound Interest"),
Headline(id:1.03, title: "Car Loan")
]
let geoArea = [
Headline(id: 2.01, title: "Triangle"),
Headline(id: 2.02, title: "Rectangle"),
Headline(id: 2.03, title: "Parallelogram"),
Headline(id: 2.04, title: "Circle")
]
let geoVolume = [
Headline(id: 2.11, title: "Cube"),
Headline(id: 2.12, title: "Cone"),
Headline(id: 2.13, title: "Cylinder"),
Headline(id: 2.14, title: "Sphere")
]
let geoSA = [
Headline(id: 2.21, title: "Cube"),
Headline(id: 2.22, title: "Rectangular Prism"),
Headline(id: 2.23, title: "Cylinder"),
Headline(id: 2.24, title: "Triangular Prism")
]
let geoLSA = [
Headline(id: 2.31, title: "Rectangular Prism"),
Headline(id: 2.32, title: "Cylinder")
]
let advPythag = [
Headline(id: 3.01, title: "Hypotenuse"),
Headline(id: 3.02, title: "Leg")
]
let advPhysics = [
Headline(id: 3.11, title: "Speed"),
Headline(id: 3.12, title: "Acceleration")
]
let advConv = [
Headline(id: 3.21, title: "Feet to Meters"),
Headline(id: 3.22, title: "Meters to Feet"),
Headline(id: 3.23, title: "Mile to Kilometer"),
Headline(id: 3.24, title: "Kilometer to Mile"),
Headline(id: 3.25, title: "Gallon to Liter"),
Headline(id: 3.26, title: "Liter to Gallon"),
Headline(id: 3.27, title: "Fraction to Decimal"),
Headline(id: 3.28, title: "Feet to Inches"),
Headline(id: 3.29, title: "Inches to Feet"),
Headline(id: 3.210, title: "Fahrenheit to Celsius"),
Headline(id: 3.211, title: "Celsius to Fahrenheit"),
]
let advOther = [
Headline(id: 3.31, title: "Square Root")
]
Your searchCalc
is of type [String?]
, therefore you can't assign a subset of your allItems
array. You can solve the problem by just grabbing the titles from the allItems
array.
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
searchCalc = [String]()
let matches = allItems.filter({$0.title.lowercased().prefix(searchText.count) == searchText.lowercased()})
for match in matches{
searchCalc.append(match.title)
}
isSearching = true
tableView.reloadData()
}