如何使用 Swift 4.2 创建搜索栏全局搜索可编码 JSON 数组值?
How to create searchBar globall search for codable JSON array value using Swift 4.2?
我的场景,我正在 Codable 结构的帮助下将 JSON
数据加载到 tableview
中。在这里,我尝试使用 storyboard
添加 Searchbar
。我不知道如何将 self.tableArray
数据与搜索栏 filtered array
同步。请提供一些想法。
我的可编码结构
struct Root: Codable {
let data: [Datum]
}
struct Datum: Codable {
let id, userID, country, card: Int
let category: Int
let title, description: String
let createDate
let user: User
enum CodingKeys: String, CodingKey {
case id
case userID = "user_id"
case country, card, category, title, description
case createDate = "create_date"
}
}
struct User: Codable {
let firstname, lastname: String
}
我的JSON代码
do {
let result = try JSONDecoder().decode(Root.self, from:data!)
self.tableArray = result.data
} catch {
print(error)
self.tableArray = []
}
我的表格视图代码
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
//return filteredData.count
return tableArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier, for: indexPath) as! CustomTableViewCell
let item = tableArray[indexPath.row]
cell.name_label.text = ("\(item.user.firstname) " + "\(item.user.lastname)")
cell.date_label.text = item.createDate
return cell
}
搜索条码
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
// When there is no text, filteredData is the same as the original data
// When user has entered text into the search box
// Use the filter method to iterate over all items in the data array
// For each item, return true if the item should be included and false if the
// item should NOT be included
filteredData = searchText.isEmpty ? names : names.filter({(dataString: String) -> Bool in
// If dataItem matches the searchText, return true to include it
return dataString.range(of: searchText, options: .caseInsensitive) != nil
})
tableView.reloadData()
}
首先需要委派搜索栏,所以添加它UISearchBarDelegate
。在此方法中,有一个功能可以检查搜索栏中的文本是否发生了变化。是
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) { }
但首先你需要声明一个变量。
var isSearching = false
并添加此功能
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
if searchBar.text == nil || searchBar.text == "" { //
isSearching = false
view.endEditing(true)
tableView.reloadData()
}
else {
isSearching = true
newArray = tableArray.filter({ value -> Bool in
guard let text = searchBar.text else { return false}
return value.title.contains(text) // According to title from JSON
})
tableView.reloadData()
}
}
newArray is the same tableArray but its empty one.
您需要检查 als numberOfRowsInSection
。如果你不修改,它会给出像 Index of out of range
这样的错误
改变它
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if isSearching {
return newArray.count
}
else {
return self.tableArray.count
}
return 0
}
更新
: 我认为问题出在这个 part.You 也需要在这里添加 isSearching
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier, for: indexPath) as! CustomTableViewCell
if isSearching{
// Need to change according to newArray
let item = newArray[indexPath.row]
cell.name_label.text = ("\(item.user.firstname) " + "\(item.user.lastname)")
cell.date_label.text = item.createDate
}
else {
let item = tableArray[indexPath.row]
cell.name_label.text = ("\(item.user.firstname) " + "\(item.user.lastname)")
cell.date_label.text = item.createDate
}
return cell
}
我的场景,我正在 Codable 结构的帮助下将 JSON
数据加载到 tableview
中。在这里,我尝试使用 storyboard
添加 Searchbar
。我不知道如何将 self.tableArray
数据与搜索栏 filtered array
同步。请提供一些想法。
我的可编码结构
struct Root: Codable {
let data: [Datum]
}
struct Datum: Codable {
let id, userID, country, card: Int
let category: Int
let title, description: String
let createDate
let user: User
enum CodingKeys: String, CodingKey {
case id
case userID = "user_id"
case country, card, category, title, description
case createDate = "create_date"
}
}
struct User: Codable {
let firstname, lastname: String
}
我的JSON代码
do {
let result = try JSONDecoder().decode(Root.self, from:data!)
self.tableArray = result.data
} catch {
print(error)
self.tableArray = []
}
我的表格视图代码
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
//return filteredData.count
return tableArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier, for: indexPath) as! CustomTableViewCell
let item = tableArray[indexPath.row]
cell.name_label.text = ("\(item.user.firstname) " + "\(item.user.lastname)")
cell.date_label.text = item.createDate
return cell
}
搜索条码
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
// When there is no text, filteredData is the same as the original data
// When user has entered text into the search box
// Use the filter method to iterate over all items in the data array
// For each item, return true if the item should be included and false if the
// item should NOT be included
filteredData = searchText.isEmpty ? names : names.filter({(dataString: String) -> Bool in
// If dataItem matches the searchText, return true to include it
return dataString.range(of: searchText, options: .caseInsensitive) != nil
})
tableView.reloadData()
}
首先需要委派搜索栏,所以添加它UISearchBarDelegate
。在此方法中,有一个功能可以检查搜索栏中的文本是否发生了变化。是
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) { }
但首先你需要声明一个变量。
var isSearching = false
并添加此功能
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
if searchBar.text == nil || searchBar.text == "" { //
isSearching = false
view.endEditing(true)
tableView.reloadData()
}
else {
isSearching = true
newArray = tableArray.filter({ value -> Bool in
guard let text = searchBar.text else { return false}
return value.title.contains(text) // According to title from JSON
})
tableView.reloadData()
}
}
newArray is the same tableArray but its empty one.
您需要检查 als numberOfRowsInSection
。如果你不修改,它会给出像 Index of out of range
改变它
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if isSearching {
return newArray.count
}
else {
return self.tableArray.count
}
return 0
}
更新
: 我认为问题出在这个 part.You 也需要在这里添加 isSearching
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier, for: indexPath) as! CustomTableViewCell
if isSearching{
// Need to change according to newArray
let item = newArray[indexPath.row]
cell.name_label.text = ("\(item.user.firstname) " + "\(item.user.lastname)")
cell.date_label.text = item.createDate
}
else {
let item = tableArray[indexPath.row]
cell.name_label.text = ("\(item.user.firstname) " + "\(item.user.lastname)")
cell.date_label.text = item.createDate
}
return cell
}