MateGreat
MateGreat

Reputation: 107

Array index out of range

I have successfully build a search function which searches and displays the TableView title and and subtitle in a detailviewcontroller. In the detailviewcontroller there's two text labels, one for the title and one for the subtitle.

Displaying the title and subtitles in the cells works fine, including tapping and seeing them in the detailviewcontroller. But when typing in the search function the app crashes due to:

fatal error: Array index out of range (lldb)

EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)

Here's all my code:

 let quotes = [
   "Saying1",
   "Saying2",]//End

let persons = [
    "Name1",
    "Name2",

]//End 

var filteredQuotes = [String]()
var filteredPersons = [String]()
var resultSearchController = UISearchController()

    override func viewDidLoad() {
        super.viewDidLoad()

        self.resultSearchController = UISearchController(searchResultsController: nil)
        self.resultSearchController.searchResultsUpdater = self

        self.resultSearchController.dimsBackgroundDuringPresentation = false
        self.resultSearchController.searchBar.sizeToFit()

        self.tableView.tableHeaderView = self.resultSearchController.searchBar

        self.tableView.reloadData()


override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    // #warning Incomplete implementation, return the number of sections
    return 1    }

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    // #warning Incomplete implementation, return the number of rows

    if self.resultSearchController.active
    {
        return self.filteredQuotes.count
    }
    else
    {
        return self.quotes.count
         }

}

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as UITableViewCell?

    if self.resultSearchController.active
    {
        cell!.textLabel?.text = self.filteredQuotes[indexPath.row]
        cell!.detailTextLabel?.text = self.filteredPersons[indexPath.row] //THE ERROR OCCURS HERE
    }
    else
    {
        cell!.textLabel?.text = self.quotes[indexPath.row]
        cell!.detailTextLabel?.text = self.persons[indexPath.row]
    }

    return cell!
}

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "SendDataSegue" {
        if let destination = segue.destinationViewController as? SearchDetailViewController {

            let path = tableView.indexPathForSelectedRow
            let cell = tableView.cellForRowAtIndexPath(path!)
            destination.viaSegue = (cell?.textLabel?.text!)!
            destination.viaSeguePerson =(cell?.detailTextLabel?.text!)!
        }
    }
}

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    _ = tableView.indexPathForSelectedRow!
    if let _ = tableView.cellForRowAtIndexPath(indexPath) {
        self.performSegueWithIdentifier("SendDataSegue", sender: self)
    }

}


func updateSearchResultsForSearchController(searchController: UISearchController) {

    self.filteredQuotes.removeAll(keepCapacity: false)
    self.filteredPersons.removeAll(keepCapacity: false)

    let searchPredicate = NSPredicate(format: "SELF CONTAINS [c] %@", searchController.searchBar.text!)

    let Quotesarray = (self.quotes as NSArray).filteredArrayUsingPredicate(searchPredicate)

    self.filteredQuotes = Quotesarray as! [String]

    let Personsarray = (self.persons as NSArray).filteredArrayUsingPredicate(searchPredicate)

    self.filteredPersons = Personsarray as! [String]

    self.tableView.reloadData()
}

Upvotes: 0

Views: 633

Answers (1)

Russell
Russell

Reputation: 5554

As @Larme and @Fogmeister suggest, you can improve this with a structured array - here's an example of how you might do that part.

define a struct to hold your data like this

struct Quotes
{
    var person : String
    var quote  : String
}

and the initialise it like this

let quotes = [Quotes(person: "name 1", quote: "saying 1"),
               Quotes(person: "name 2", quote: "saying 2")  ]

alternatively, of course, you could initialise an empty array, and then append data as you retrieve it from somewhere - database, or user input

var quotes : [Quotes] = []

let quote1 = Quotes(person: "name 3", quote: "saying 3")        
quotes.append(quote1)

or

quotes.append(Quotes(person: "name 4", quote: "saying 4"))

Upvotes: 2

Related Questions