Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/94.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 筛选使用Firebase填充的多个阵列_Ios_Swift_Firebase Realtime Database - Fatal编程技术网

Ios 筛选使用Firebase填充的多个阵列

Ios 筛选使用Firebase填充的多个阵列,ios,swift,firebase-realtime-database,Ios,Swift,Firebase Realtime Database,我有一个文本字段作为搜索视图,然后我的TableView显示我的结果。TableView的原型单元由两个标签组成。第一个标签由schoolNameArray填充。第二个标签由schoolTownArray+“,”+schoolCountryArray填充。所有3个阵列都通过Firebase填充。下面显示的搜索功能的图像 如果没有第二个标签,我可以很好地过滤一个数组。我的问题是我只能在一个数组上进行SearchView筛选,而不是在三个数组上。例如,我输入'Academy'和'Azhar Aca

我有一个文本字段作为搜索视图,然后我的TableView显示我的结果。TableView的原型单元由两个标签组成。第一个标签由schoolNameArray填充。第二个标签由schoolTownArray+“,”+schoolCountryArray填充。所有3个阵列都通过Firebase填充。下面显示的搜索功能的图像

如果没有第二个标签,我可以很好地过滤一个数组。我的问题是我只能在一个数组上进行SearchView筛选,而不是在三个数组上。例如,我输入'Academy'和'Azhar Academy'显示,但如果我输入'Bolton',我会得到“致命错误:索引超出范围”,因为我无法正确填充filteredSchoolLocationArray

我的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
    }
}


您应该使用结构来表示数据。你会过得轻松得多。您还有一些问题需要解决,但这应该会让您继续:

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
    }
}

感谢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
    }
}