Home > Back-end >  Swift: having trouble getting segue to show details from selecting item in a view collection
Swift: having trouble getting segue to show details from selecting item in a view collection

Time:03-10

I am trying to set a View Collection to segue to a item's details when the item's image is clicked on. Here is the code I have. However, when I try, I get the error, Thread 1: Fatal error: Index out of range, next to this line of code: destinationController.shop = shopping[indexPaths[0].row]

Here is my full code for the collection view controller. Can anyone tell me what I am doing wrong?

import UIKit
private let reuseIdentifier = "Cell"

class shopCollectionViewController: UICollectionViewController {

@IBAction func unwindToMain(segue: UIStoryboardSegue){
        
    }
var shopping: [Shop] = [Shop(image:"blueTshirt", name:"blueTshirt", price: 10), Shop(image:"blackTshirt", name:"blackTshirt", price: 10), Shop(image:"lightblueTshirt", name:"lightblueTshirt", price: 10), Shop(image:"whiteTshirt", name:"whiteTshirt", price: 10)]



override func viewDidLoad() {
    super.viewDidLoad()

    // Uncomment the following line to preserve selection between presentations
    // self.clearsSelectionOnViewWillAppear = false

    // Do any additional setup after loading the view.
}

/*
// MARK: - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

// MARK: UICollectionViewDataSource

override func numberOfSections(in collectionView: UICollectionView) -> Int {
    // #warning Incomplete implementation, return the number of sections
    return 1
}


override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    // #warning Incomplete implementation, return the number of items
    return shopping.count
}

override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "dataCell", for: indexPath) as! shopCollectionViewCell

    // Configure the cell
    let item = shopping[indexPath.row]
    cell.itemImage.image = UIImage(named: item.image)

    return cell
}

override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
       performSegue(withIdentifier: "showDetail", sender: nil)
   }

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "showDetail" {
        if let indexPaths = collectionView.indexPathsForSelectedItems{
            let destinationController = segue.destination as! itemDetailsViewController
               destinationController.shop = shopping[indexPaths[0].row]
               collectionView.deselectItem(at: indexPaths[0], animated: false)
           }
       }

CodePudding user response:

When you use collectionView maybe you should use indexPath.item instead of indexPath.row

CodePudding user response:

A more reliable way than indexPathsForSelectedItems is to pass the index path while calling performSegue.

And deselect the cell right inside didSelectItemAt

override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
   performSegue(withIdentifier: "showDetail", sender: indexPath)
   collectionView.deselectItem(at: indexPath, animated: false)
}

And replace prepare(for with

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "showDetail" {
        let indexPath = sender as! IndexPath
        let destinationController = segue.destination as! itemDetailsViewController
        destinationController.shop = shopping[indexPath.item]
    }
}
  • Related