过滤2个数组时,Swift Searchbar App崩溃

时间:2018-02-23 01:05:28

标签: arrays swift uisearchbar

我用两个数组填充tableview。关于在搜索栏中输入两个字符导致应用程序崩溃后,我一直收到错误,因为数组计数不同。我已经尝试了一段时间,但我无法找到解决方案。与此类似的帖子有2个数组,但对于每个'设置'我有一个包含数据的数组(数据和PostUser),以及一个包含相同数据的数组,但是已过滤(filteredData和PostUserFiltered。我无法将他们的解决方案应用到我的。

import UIKit
import Firebase

class SearchPostsController: UIViewController, UITableViewDataSource, UISearchBarDelegate {

    @IBOutlet weak var searchBar: UISearchBar!
    @IBOutlet weak var tableView: UITableView!

    var data:[String] = []

    var filteredData: [String] = [String]()
    var idArray:[String] = []
    var postUser:[String] = []
    var postUserFiltered: [String] = [String]()

    override func viewDidLoad() {
        super.viewDidLoad()

        let ourId = UserDefaults.standard.object(forKey: "SearchIds")
        print("Our ids\(ourId!)")
        self.idArray = ourId! as! [String]
        for singleId in idArray {

            Database.database().reference().child("\(UserData().mySchool!)/posts").child("\(singleId)/message").observe(.value, with: { (snapshot) in
                    if let test = snapshot.value as? String!{
                            self.data.append(test)
                            print(test)
                            self.filteredData = self.data
                            print("data: \(self.filteredData)")
                            self.tableView.reloadData()
                        }
                    })
                }
        self.filteredData = self.data
        ///////////////////////////////////////////////////////////////
        for singleId in idArray {

            Database.database().reference().child("\(UserData().mySchool!)/posts").child("\(singleId)/username").observe(.value, with: { (snapshot) in
                if let test = snapshot.value as? String!{
                    self.postUser.append(test)
                    print(test)
                    self.postUserFiltered = self.postUser
                    print("data: \(self.postUserFiltered)")
                    self.tableView.reloadData()
                }
            })
        }
        self.postUserFiltered = self.postUser
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell(style: .subtitle, reuseIdentifier: "cell")

            cell.textLabel?.text = self.filteredData[indexPath.row]
            cell.detailTextLabel?.text = self.postUserFiltered[indexPath.row]

        return cell
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return postUserFiltered.count
    }
    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {

        filteredData = searchText.isEmpty ? data : data.filter { (item: String) -> Bool in
            // If dataItem matches the searchText, return true to include it
            return item.range(of: searchText, options: .caseInsensitive, range: nil, locale: nil) != nil
        }
        ////////////////for the username now
        postUserFiltered = searchText.isEmpty ? postUser : postUser.filter { (item: String) -> Bool in
            // If dataItem matches the searchText, return true to include it
            return item.range(of: searchText, options: .caseInsensitive, range: nil, locale: nil) != nil
        }

        self.tableView.reloadData()
    }

    func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
        searchBar.showsCancelButton = false
        searchBar.text = ""
        searchBar.resignFirstResponder()
    }

    func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
        self.searchBar.showsCancelButton = true
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

1 个答案:

答案 0 :(得分:0)

错误是因为2个数组的长度不匹配,即filteredData和postUserFiltered。

原因是您根据滤波数据是否包含在搜索字段V中输入的文本来过滤您的滤波数据。只有过滤后用户并在他人的同时接受他的相应帖子。

我建议你使用字典而不是2个不同的数组,其中键是postUser,值是Data。

您可以根据键过滤字典,从而保留postUser与正确数据的对应关系

如果你还想使用2个数组,你可以使用下面的代码;我已经为你修改了代码。

import UIKit
import Firebase

class SearchPostsController: UIViewController, UITableViewDataSource, UISearchBarDelegate {

    @IBOutlet weak var searchBar: UISearchBar!
    @IBOutlet weak var tableView: UITableView!

    var data:[String] = []

    var filteredData: [String] = []
    var idArray:[String] = []
    var postUser:[String] = []
    var postUserFiltered: [String] = []
    var mapping: [String:Int] = [:]

    override func viewDidLoad() {
        super.viewDidLoad()

        let ourId = UserDefaults.standard.object(forKey: "SearchIds")
        print("Our ids\(ourId!)")
        self.idArray = ourId! as! [String]
        var index = 0;
        for singleId in idArray {

            Database.database().reference().child("\(UserData().mySchool!)/posts").child("\(singleId)/message").observe(.value, with: { (snapshot) in
                    if let test = snapshot.value as? String!{
                            self.data.append(test)
                            print(test)
                            self.filteredData = self.data
                            print("data: \(self.filteredData)")
                            self.tableView.reloadData()
                        }
                    })
                }
        self.filteredData = self.data
        ///////////////////////////////////////////////////////////////
        for singleId in idArray {

            Database.database().reference().child("\(UserData().mySchool!)/posts").child("\(singleId)/username").observe(.value, with: { (snapshot) in
                if let test = snapshot.value as? String!{
                    self.postUser.append(test)
                    print(test)
                    self.mapping[test] = index;
                    self.postUserFiltered = self.postUser
                    print("data: \(self.postUserFiltered)")
                    self.tableView.reloadData()
                }
            })
          index += 1;
        }
        self.postUserFiltered = self.postUser
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell(style: .subtitle, reuseIdentifier: "cell")

            cell.textLabel?.text = self.data[self.mapping[self.postUserFiltered[indexPath.row]]]
            cell.detailTextLabel?.text = self.postUserFiltered[indexPath.row]

        return cell
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if let postUserFiltered = self.postUserFiltered{
          return postUserFiltered.count
        }
        return 0
    }
    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {

        filteredData = searchText.isEmpty ? data : data.filter { (item: String) -> Bool in
            // If dataItem matches the searchText, return true to include it
            return item.range(of: searchText, options: .caseInsensitive, range: nil, locale: nil) != nil
        }
        ////////////////for the username now
        postUserFiltered = searchText.isEmpty ? postUser : postUser.filter { (item: String) -> Bool in
            // If dataItem matches the searchText, return true to include it
            return item.range(of: searchText, options: .caseInsensitive, range: nil, locale: nil) != nil
        }

        self.tableView.reloadData()
    }

    func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
        searchBar.showsCancelButton = false
        searchBar.text = ""
        searchBar.resignFirstResponder()
    }

    func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
        self.searchBar.showsCancelButton = true
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}