Search code examples
iosswiftxcodeuicollectionviewcollectionview

Cannot pass data from collection view to detail view in Xcode


I am a Swift beginner attempting to pass the corresponding name and image of the product contained within a cell of a collection view. I have created a singleton and a data file to simulate pulling this info from the internet. I am struggling to assign the values of the collection view cell to the outlets on the detail view controller. Where am I going wrong? I am struggling to understand how to assign these value correctly. Here are my files:

Collection View File

import UIKit

class ProductVC: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {

@IBOutlet weak var collectionView: UICollectionView!

override func viewDidLoad() {
    super.viewDidLoad()
    collectionView.delegate = self
    collectionView.dataSource = self
}

@IBAction func backButtonPressed(_ sender: Any) {
    dismiss(animated: true, completion: nil)
}

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return DataServices.instance.getProducts().count
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ProductCell", for: indexPath) as? ProductCell {
        let product = DataServices.instance.getProducts()[indexPath.row]
        cell.updateView(product: product)
        return cell
    }
    return ProductCell()
}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "ProductDetailVC" {
        var productDetailVC = segue.destination as! ProductDetailVC
        let cell = sender as! UICollectionViewCell
        let indexPath = collectionView.indexPath(for: cell)
        let product = DataServices.instance.getProducts()[(indexPath?.row)!]
    }
}


}

Product Detail View Controller

import UIKit

class ProductDetailVC: UIViewController {

@IBOutlet weak var productName: UILabel!
@IBOutlet weak var productImageView: UIImageView!

var product: Product?

override func viewDidLoad() {
    super.viewDidLoad()
}

func updateView() {
    productName.text = product?.name
    productImageView.image = UIImage(named: (product?.imageName)!)
}


}

Product Model

import Foundation

struct Product {

private(set) public var name: String
private(set) public var imageName: String

init(name: String, imageName: String) {
    self.name = name
    self.imageName = imageName
}

}

Data Model

import Foundation

class DataServices {

static var instance = DataServices()
var productIndex = 0 

private(set) public var categories = [
    Category(imageName: "backpackingBG", title: "BACKPACKING"),
    Category(imageName: "campingBG", title: "CAMPING"),
    Category(imageName: "divingBG", title: "DIVING"),
    Category(imageName: "fishingBG", title: "FISHING"),
    Category(imageName: "hikingBG", title: "HIKING"),
    Category(imageName: "rvBG", title: "RV LIFE")
]

func getCategories() -> [Category] {
    return categories
}

private let products = [
    Product(name: "SLEEPING BAG", imageName: "sleepingBag"),
    Product(name: "CAMPING STOVE", imageName: "campingStove"),
    Product(name: "FOOD COOLER", imageName: "foodCooler"),
    Product(name: "PARACORD BRACELET", imageName: "paracordBracelet"),
    Product(name: "PUP TENT", imageName: "pupTent"),
    Product(name: "TACTICAL KNIFE", imageName: "tacticalKnife")
]

func getProducts() -> [Product] {
    return products
}

}

Solution

  • You have forgot to pass product,for Pass product

     override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "ProductDetailVC" {
            var productDetailVC = segue.destination as! ProductDetailVC
            let cell = sender as! UICollectionViewCell
            let indexPath = collectionView.indexPath(for: cell)
            let product = DataServices.instance.getProducts()[(indexPath?.row)!]
            productDetailVC.product = product
        }
    }
    

    And in ProductDetailVC for update UI

    override func viewDidLoad() {
        super.viewDidLoad()
        self.updateView()
    }