如何使用 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

}