【问题标题】:Filter multiple arrays that are populated using Firebase过滤使用 Firebase 填充的多个数组
【发布时间】:2020-04-12 17:40:55
【问题描述】:

我有一个 TextField 用作 SearchView,然后我的 TableView 显示我的结果。 TableView 的原型单元由两个标签组成。第一个标签由 schoolNameArray 填充。第二个标签由 schoolTownArray + ", " + schoolCountryArray 填充。所有 3 个数组都通过 Firebase 填充。搜索功能的图片如下所示。

没有第二个标签,我可以很好地过滤一个数组。我的问题是我只能在一个数组上制作我的 SearchView 过滤器,而不是三个。例如。我输入“Academy”和“Azhar Academy”节目,但如果我输入“Bolton”,我会收到“致命错误:索引超出范围”,因为我无法正确填充过滤后的SchoolLocationArray。

我的 Android 版本的项目从搜索框中检索文本,然后在 firebase 查询的 for 循环中处理过滤。如何使用以下代码在此处执行此操作(或达到相同的结果):

class SearchViewController: UIViewController {

    @IBOutlet weak var editTextSearch: UITextField!
    @IBOutlet weak var tableViewSearch: UITableView!

    var schoolNameArray = [String]()
    var schoolTownArray = [String]()
    var schoolCountryArray = [String]()
    var filteredSchoolNameArray = [String]()
    var filteredSchoolLocationArray = [String]()
    var searching  = false

    override func viewDidLoad() {
        super.viewDidLoad()

        let schoolDatabase = Database.database().reference().child("Timetable")
        schoolDatabase.observeSingleEvent(of: .value, with: { (snapshot) in
            for child in snapshot.children {
                let schoolID = child as! DataSnapshot
                let stringApproved = schoolID.childSnapshot(forPath: "Approved").value
                if stringApproved as? String == "Yes" {
                    let stringSchoolName = schoolID.childSnapshot(forPath: "Name").value as! String
                    let stringSchoolTown = schoolID.childSnapshot(forPath: "Town or City").value as! String
                    let stringSchoolCountry = schoolID.childSnapshot(forPath: "Country").value as! String
                    self.schoolNameArray.append(stringSchoolName)
                    self.schoolTownArray.append(stringSchoolTown)
                    self.schoolCountryArray.append(stringSchoolCountry)
                }
            }
            self.tableViewSearch.reloadData()
        })
    }
}

extension SearchViewController: UITableViewDataSource, UITableViewDelegate {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if searching {
            return filteredSchoolNameArray.count
        } else {
            return schoolNameArray.count
        }
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let searchItem = tableView.dequeueReusableCell(withIdentifier: "SearchItem") as! SearchItemCell

        searchItem.searchItemSchoolName.text = schoolNameArray[indexPath.row]
        searchItem.searchItemSchoolLocation.text = schoolTownArray[indexPath.row] + ", " + schoolCountryArray[indexPath.row]

        if searching {
            searchItem.searchItemSchoolName.text = filteredSchoolNameArray[indexPath.row]
            searchItem.searchItemSchoolLocation.text = filteredSchoolLocationArray[indexPath.row]
        } else {
            searchItem.searchItemSchoolName.text = schoolNameArray[indexPath.row]
            searchItem.searchItemSchoolLocation.text = schoolTownArray[indexPath.row] + ", " + schoolCountryArray[indexPath.row]
        }

        return searchItem
    }
}

extension SearchViewController: UITextFieldDelegate {    
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        filteredSchoolNameArray = schoolNameArray.filter({$0.lowercased().contains((textField.text?.lowercased())!)})
        searching = true
        tableViewSearch.reloadData()
        return true
    }
}

【问题讨论】:

    标签: ios swift firebase-realtime-database


    【解决方案1】:

    您应该使用结构来表示您的数据。你会有一个更轻松的时间。您还有一些问题需要解决,但这应该可以帮助您:

    class SearchViewController: UIViewController {
    
        struct School {
            let name: String
            let town: String
            let country: String
        }
    
        @IBOutlet weak var editTextSearch: UITextField!
        @IBOutlet weak var tableViewSearch: UITableView!
    
        var schools: [School] = []
        var filteredSchools: [School] = []
    
        var searching = false
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            // ...
    
            if stringApproved as? String == "Yes" {
                let name = schoolID.childSnapshot(forPath: "Name").value as! String
                let town = schoolID.childSnapshot(forPath: "Town or City").value as! String
                let country = schoolID.childSnapshot(forPath: "Country").value as! String
    
                self.schools.append(.init(name: name, town: town, country: country))
            }
    
            // ...
        }
    
        // ...
    }
    
    extension SearchViewController: UITextFieldDelegate {
        func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
            guard let text = textField.text else { return true }
            filteredSchools = schools.filter({ $0.name.lowercased().contains(text.lowercased()) })
            searching = true
            tableViewSearch.reloadData()
            return true
        }
    }
    

    【讨论】:

      【解决方案2】:

      感谢 Rob 的帮助,下面是最终代码。

      class SearchViewController: UIViewController {
      
          @IBOutlet weak var editTextSearch: UITextField!
          @IBOutlet weak var tableViewSearch: UITableView!
      
          struct School {
              let schoolName: String
              let schoolTown: String
              let schoolCountry: String
          }
      
          var schoolArray: [School] = []
          var filteredSchoolArray: [School] = []
          var searching  = false
      
          override func viewDidLoad() {
              super.viewDidLoad()
              // Do any additional setup after loading the view.
      
              let schoolDatabase = Database.database().reference().child("Timetable")
              schoolDatabase.observeSingleEvent(of: .value, with: { (snapshot) in
                  for child in snapshot.children {
                      let schoolID = child as! DataSnapshot
                      let stringApproved = schoolID.childSnapshot(forPath: "Approved").value
                      if stringApproved as? String == "Yes" {
                          // stringSchoolID = schoolID.key
                          let stringSchoolName = schoolID.childSnapshot(forPath: "Name").value as! String
                          let stringSchoolTown = schoolID.childSnapshot(forPath: "Town or City").value as! String
                          let stringSchoolCountry = schoolID.childSnapshot(forPath: "Country").value as! String
                          self.schoolArray.append(.init(schoolName: stringSchoolName, schoolTown: stringSchoolTown, schoolCountry: stringSchoolCountry))
                      }
                  }
                  self.tableViewSearch.reloadData()
              })
              //filteredSchoolArray.removeAll()
          }
      }
      
      extension SearchViewController: UITableViewDataSource, UITableViewDelegate {
          func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
              if searching {
                  return filteredSchoolArray.count
              } else {
                  return schoolArray.count
              }
          }
      
          func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
              let searchItem = tableView.dequeueReusableCell(withIdentifier: "SearchItem") as! SearchItemCell
      
              if searching {
                  let filteredSchoolItem = filteredSchoolArray[indexPath.row]
                  searchItem.searchItemSchoolName.text = filteredSchoolItem.schoolName
                  searchItem.searchItemSchoolLocation.text = filteredSchoolItem.schoolTown + ", " + filteredSchoolItem.schoolCountry
              } else {
                  let schoolItem = schoolArray[indexPath.row]
                  searchItem.searchItemSchoolName.text = schoolItem.schoolName
                  searchItem.searchItemSchoolLocation.text = schoolItem.schoolTown + ", " + schoolItem.schoolCountry
              }
      
              return searchItem
          }
      }
      
      extension SearchViewController: UITextFieldDelegate {
          func textFieldShouldClear(_ textField: UITextField) -> Bool {
              editTextSearch.resignFirstResponder()
              editTextSearch.text = ""
              filteredSchoolArray.removeAll()
              tableViewSearch.reloadData()
              return true
          }
      
          func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
              guard let text = textField.text else { return true }
              filteredSchoolArray = schoolArray.filter({$0.schoolName.lowercased().contains(text.lowercased()) ||
                  $0.schoolTown.lowercased().contains(text.lowercased()) ||
                  $0.schoolCountry.lowercased().contains(text.lowercased())})
              searching = true
              tableViewSearch.reloadData()
              return true
          }
      }
      
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-05-18
        • 2021-06-06
        • 1970-01-01
        • 2019-10-25
        • 2019-06-15
        • 1970-01-01
        • 2019-12-21
        • 1970-01-01
        相关资源
        最近更新 更多