在表格视图中使用搜索栏时,Swift致命错误索引超出范围

时间:2019-06-27 03:16:20

标签: swift tableview searchbar

我尝试使用tableView加载json数据,并且想使用uiSearchBar添加搜索数据,数据搜索良好,但是当我尝试在searchBar上按“ x”按钮或当我尝试对输入进行退格时,它就会崩溃。有人帮忙吗?还是应该更改搜索方式?谢谢您的帮助。我仍然是新手,所以如果有更好的搜索方法,请告诉我:)

  struct ProjectSumName: Decodable {
     let id : Int
      let name : String

enum CodingKeys : String, CodingKey {
    case id = "id"
    case name = "name"
  }
}


 class ProjectSumController: UIViewController {

  @IBOutlet weak var SearchBar: UISearchBar!
  @IBOutlet weak var ProjectSumTableView: UITableView!

  var projectSum = [ProjectSumName]()
  var filterProject : [ProjectSumName] = [ProjectSumName]()
  var isSearch : Bool = false

  override func viewDidLoad() {
    super.viewDidLoad()
    SearchBar.delegate = self

      Loading()
      let jsonUrl = "http://\(GlobalVariable.ip):7000/api/projectApi?UserId=\(GlobalVariable.UserIdProjectSum)"
    guard let url = URL(string: jsonUrl) else { return }

    URLSession.shared.dataTask(with: url) { (data, response, error) in
        guard let data = data else { return }
        do{
            let projectsum = try JSONDecoder().decode([ProjectSumName].self, from: data)
            self.projectSum = projectsum
            self.filterProject = projectsum
            DispatchQueue.main.async {
                SVProgressHUD.dismiss()
                self.ProjectSumTableView.reloadData()
            }
        }catch {
            print(error)
        }
    }.resume()
  }
} 



   extension ProjectSumController : UISearchBarDelegate,  UITableViewDelegate,UITableViewDataSource{


   func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    if isSearch{
        return filterProject.count
    }else{
        return projectSum.count
    }
}
  func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let proc = projectSum[indexPath.row]
    let proc1 = filterProject[indexPath.row]
    guard let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as? ProjectSumTableCell else {return UITableViewCell()}

    if isSearch{
        cell.NameLbl.text = proc1.name
    }else{
        cell.NameLbl.text = proc.name
    }
    return cell
}

   func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let sum = projectSum[indexPath.row]
    let sum1 = filterProject[indexPath.row]

    if isSearch{
        performSegue(withIdentifier: "Segue", sender: sum1)
        let projectIDs = sum1.id
        GlobalVariable.ProjectId = String(projectIDs)
    }else{
        performSegue(withIdentifier: "Segue", sender: sum)
        let projectID = sum.id
        GlobalVariable.ProjectId = String(projectID)
    }
}

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

        if searchText.isEmpty{
            self.isSearch = false;
            self.ProjectSumTableView.reloadData()
        } else {
            self.filterProject = self.projectSum.filter({  (ProjectSumName) -> Bool in

                let tmp : NSString = NSString.init(string: ProjectSumName.name)
                let range = tmp.range(of: searchText, options: NSString.CompareOptions.caseInsensitive)

                return range.location != NSNotFound && range.location == 0
            })
            if(self.filterProject.count == 0){
                self.isSearch = false;
            }else{
                self.isSearch = true;
            }
            self.ProjectSumTableView.reloadData()
        }
    }

“致命错误:索引超出范围 2019-06-27 09:43:46.167472 + 0700 ImmobiTracker [806:30114]致命错误:索引超出范围”

崩溃会出现,我尝试清除搜索栏的所有内容...因此,当我尝试键入第一次以搜索其过滤数据时,但是当我尝试清除搜索栏时,它弹出崩溃

2 个答案:

答案 0 :(得分:1)

您在两个地方遇到此错误。

  1. 在cellForRowAt中:

    let proc = projectSum[indexPath.row]
    let proc1 = filterProject[indexPath.row]
    
  2. didSelectRowAt

    let sum = projectSum[indexPath.row]
    let sum1 = filterProject[indexPath.row]
    

为什么

您正尝试从filterProject中获取一个元素,而不使用isSearch,即filterPoject数组为空。当isSearchfalse时,会发生错误,因为您正试图从空数组中获取元素。

解决方法

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let sum: ProjectSumName
    if isSearch{
        sum = filterProject[indexPath.row]
    }else{
        sum = projectSum[indexPath.row]
    }
    GlobalVariable.ProjectId = String(sum.id)
    performSegue(withIdentifier: "Segue", sender: sum)
}


func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    guard let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as? ProjectSumTableCell else {return UITableViewCell()}

    let proc: ProjectSumName
    if isSearch{
        proc = filterProject[indexPath.row]
    }else{
        proc = projectSum[indexPath.row]
    }
    cell.NameLbl.text = proc.name
    return cell
}

答案 1 :(得分:-1)

 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    guard let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as? ProjectSumTableCell else {return UITableViewCell()}
    if isSearch {
        if 0..<filterProject.count ~= indexPath.row {
         let proc1 = filterProject[indexPath.row]
         cell.NameLbl.text = proc1.name
        }
    } else {
      if 0..<projectSum.count ~= indexPath.row {
        let proc = projectSum[indexPath.row]
        cell.NameLbl.text = proc.name
      }
    }
    return cell
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    if isSearch{
        if 0..<filterProject.count ~= indexPath.row {
         let sum1 = filterProject[indexPath.row]
         performSegue(withIdentifier: "Segue", sender: sum1)
         let projectIDs = sum1.id
         GlobalVariable.ProjectId = String(projectIDs)
        }
    }else{
        if 0..<projectSum.count ~= indexPath.row {
          let sum = projectSum[indexPath.row]
          performSegue(withIdentifier: "Segue", sender: sum)
          let projectID = sum.id
          GlobalVariable.ProjectId = String(projectID)
        }
    }
}