0

I am creating a TableView that starts with an image at the top, approximately 5 cells of parsed json, another image, approximately 3 more cells of parsed json, and another image.

I have 3 custom nibs that I am using. Each one is unique.

I get an "Index out of range" error on the line "let item = page?.collapsibles[indexForSecondSetTableViewCells]"

Here is my code:

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

    let currentIndex = indexPath.row - 1
    let numberofCarousels = self.page?.carousels.count
    let indexAfterCarousels = numberofCarousels ?? 00 + 1
    let indexForSecondSetTableViewCells = indexAfterCarousels + 1

    if indexPath.row == 0 {

        let cell = tableView.dequeueReusableCell(withIdentifier: "pipesOne", for: indexPath) as! Pipes1TableViewCell

        cell.pipesOne.image = UIImage(named: "WhatsNew1")

        return cell
    }

    if indexPath.row == indexAfterCarousels {

        let cell = tableView.dequeueReusableCell(withIdentifier: "pipesOne", for: indexPath) as! Pipes1TableViewCell

        cell.pipesOne.image = UIImage(named: "WhatsNew2")

        return cell
    }

    if indexPath.row == indexForSecondSetTableViewCells {

        let cell = tableView.dequeueReusableCell(withIdentifier: "collapsibleCell", for: indexPath) as! CollapsiblesTableViewCell

        let item = page?.collabsible[indexForSecondSetTableViewCells]

        cell.collabsibleTitle.text = item?.title
        cell.collabsibleDescription.text = item?.content

        return cell
    }

    let cell = tableView.dequeueReusableCell(withIdentifier: "newsTableViewCell", for: indexPath) as! NewsTableViewCell


    let item = page?.carousels[currentIndex]

    cell.newsTitle.text = item?.title
    cell.newsText.text = item?.caption
    cell.newsImage.kf.setImage(with: page?.carousels[currentIndex].imageURL)

    return cell

}

        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return (page?.carousels.count ?? 0) + 1 + (page?.collapsibles.count ?? 0)
}

Update: I simplified the code to use the same json object twice and so that each item maps to exactly the cell that it should go to and I still get the "Fatal error: Index out of range" error at row 7 with let item = page?.collapsible[indexPath.row]

New code:

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

    if indexPath.row == 0 {

        let cell = tableView.dequeueReusableCell(withIdentifier: "pipesOne", for: indexPath) as! Pipes1TableViewCell

        cell.pipesOne.image = UIImage(named: "WhatsNew1")

        return cell
    }

    if indexPath.row == 1 {

        let cell = tableView.dequeueReusableCell(withIdentifier: "newsTableViewCell", for: indexPath) as! NewsTableViewCell

        let item = page?.carousels[indexPath.row]

        cell.newsTitle.text = item?.title
        cell.newsText.text = item?.caption
        cell.newsImage.kf.setImage(with: page?.carousels[indexPath.row].imageURL)

        return cell
    }

    if indexPath.row == 6 {

        let cell = tableView.dequeueReusableCell(withIdentifier: "pipesOne", for: indexPath) as! Pipes1TableViewCell

        cell.pipesOne.image = UIImage(named: "WhatsNew2")

        return cell
    }

    if indexPath.row == 7 {

        let cell = tableView.dequeueReusableCell(withIdentifier: "collapsibleCell", for: indexPath) as! CollapsiblesTableViewCell

        let item = page?.collapsibles[indexPath.row]

        cell.collabsibleTitle.text = item?.title
        cell.collabsibleDescription.text = item?.content


        return cell
    }
    return UITableViewCell()
}


func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return 11
}

1 Answers1

0

Try to print("\(indexPath)") in

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    print("\(indexPath)")
}

Then you will know how many rows it successfully shows before crash. Then in cellForRowAt put conditional break point such it stops when indexPath is the one it crashed. Now do po (page?.carousels.count ?? 0) + 1 + (page?.collapsibles.count ?? 0) to see how many rows your tableview has. Most definitely indexForSecondSetTableViewCells is more than the number of rows

Samuel Liew
  • 76,741
  • 107
  • 159
  • 260
  • It crashes after row 6, so once I'm trying to place the second set of JSON data into the rows after the 6th cell. It seems like it might be the line "if indexPath.row == indexForSecondSetTableViewCells" but I'm not sure what else I could put there, but it's not really referring to a row any more, it's saying attribute the data to a single cell, I think. When I print `print((page?.carousels.count ?? 0) + 1 + (page?.collapsibles.count ?? 0))` with the break point I get: 1 9 9 9 9 9 9 9 – Allissa Hertz Nov 07 '19 at 18:45
  • when it breaks at indexPath.row == 6, Do not print((page?.carousels.count ?? 0) + 1 + (page?.collapsibles.count ?? 0)). use po (page?.carousels.count ?? 0) + 1 + (page?.collapsibles.count ?? 0) in the console. It should give you one number which less than indexForSecondSetTableViewCells –  Nov 07 '19 at 18:51
  • It gives me 9, which is the correct value for the total number of cells altogether counting from 0. – Allissa Hertz Nov 07 '19 at 19:06
  • which means your datasource has 10 items. Is page?.collapsibles.count also 10? If it is not the case, the data for your 10th item for 10th row is NOT in index 9 in page?.collapsibles[]. –  Nov 07 '19 at 19:08
  • I made some adjustments based on this feedback, but I'm still not seeing the expected result. I changed number of rows to return 10. I also changed `if indexPath.row == indexForSecondSetTableViewCells { let item = page?.collabsible[indexForSecondSetTableViewCells]` to `if indexPath.row == 7 { let item = page?.collapsibles[indexPath.row]` – Allissa Hertz Nov 07 '19 at 21:40