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]
}
}