jenna
jenna

Reputation: 123

Updating a tableView from a search, with custom cells

I am trying to update my tableView based on what is searched in the search bar. I have three labels that I am trying to update so when the user searches for a name, it seems the correct data with each school. But I keep getting a fatal error saying the index is out of range, but the index is one. I have been printing out the index, and I have more than 2 objects in array. The data is received from an api, and the data is displaying well, its just when I try to search.

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int)-> Int {
        if searching {
            return searchCollege.count
        }
        else {
            return resultArray.count

        }
    }
}


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

      let collegeNames = resultArray.map{$0.userSchool_name}

        names = collegeNames.filter({$0!.prefix(searchText.count) == searchText}) as! [String]

        for i in 0...resultArray.count
        {
            if names.contains(resultArray[i].userSchool_name!){
                print("Here's the value of i")
                print(i)
**gets caught at this line*** searchCollege[i].schoolName = resultArray[i].userSchool_name!
                searchCollege[i].admRate = String(resultArray[i].admission_rate!)
                searchCollege[i].actScores = String(resultArray[i].act_Scores_midCum!)
                searchCollege[i].satScores = String(resultArray[i].sat_Scores_midCum!)

            }
        }

        if (searchCollege.count == 0) {
            self.searchCollege[0].schoolName = "No Result"
            self.searchCollege[0].admRate = " "
            self.searchCollege[0].actScores = " "
            self.searchCollege[0].satScores = " "


        }
        searching = true
        tableView.reloadData()
    }

Users.swift

struct Root: Codable {
    let results : [Users]

}

struct Users: Codable {
    let userSchool_name: String?
    let admission_rate: Float64?
    let sat_Scores_midCum: Float64?
    let act_Scores_midCum: Float64?

    enum CodingKeys: String, CodingKey {
        case userSchool_name = "school.name"
        case admission_rate = "latest.admissions.admission_rate.overall"
        case sat_Scores_midCum = "latest.admissions.sat_scores.average.overall"
        case act_Scores_midCum = "latest.admissions.act_scores.midpoint.cumulative"
    }
}

Upvotes: 0

Views: 38

Answers (1)

vadian
vadian

Reputation: 285250

The for loop works only with these two forms

for i in 0...resultArray.count - 1 { ...

or (recommended)

for i in 0..<resultArray.count { ...

But there is a still more efficient syntax

for (index, element) in resultArray.enumerated()
{
    if names.contains(element.userSchool_name!){
        print("Here's the value of index", index)
        searchCollege[index].schoolName = element.userSchool_name!
        searchCollege[index].admRate = String(element.admission_rate!)
        searchCollege[index].actScores = String(element.act_Scores_midCum!)
        searchCollege[index].satScores = String(element.sat_Scores_midCum!)
    }
}

And be aware that your code will (also) crash reliably if searchCollege is empty

Edit:

According to the numberOfRowsInSection method why not simply

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

  if searchText.isEmpty {
     searchCollege.removeAll()
     searching = false
  } else {
     searchCollege = resultArray.filter{ $0!.userSchool_name.range(of: searchText, options: [.anchored, .caseInsensitive]) != nil }
     searching = true
  {
  tableView.reloadData()
}

Upvotes: 1

Related Questions