无法将数据从集合视图传递到 Xcode 中的详细视图

Posted

技术标签:

【中文标题】无法将数据从集合视图传递到 Xcode 中的详细视图【英文标题】:Cannot pass data from collection view to detail view in Xcode 【发布时间】:2018-03-28 10:44:59 【问题描述】:

我是一名 Swift 初学者,试图传递包含在集合视图单元格中的产品的相应名称和图像。我创建了一个单例和一个数据文件来模拟从互联网上提取这些信息。我正在努力将集合视图单元格的值分配给详细视图控制器上的插座。我哪里错了?我正在努力理解如何正确分配这些值。这是我的文件:

集合查看文件

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)!]
    




产品细节视图控制器

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)!)




产品型号

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



数据模型

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



【问题讨论】:

在您的代码中准备 segue productDetailVC.product = product 您没有将产品传递给 productDetailVC 【参考方案1】:

你必须实现

optional func collectionView(_ collectionView: UICollectionView, 
         didSelectItemAt indexPath: IndexPath)

  self. performSegue(withIdentifier: "ProductDetailVC", sender: indexPath.row)


//

override func prepare(for segue: UIStoryboardSegue, sender: Any?) 
 if segue.identifier == "ProductDetailVC" 
    var productDetailVC = segue.destination as! ProductDetailVC
    let index = sender as! Int
    let product = DataServices.instance.getProducts()[index]
    productDetailVC.product = product
 

【讨论】:

当我尝试在 prepareForSegue 中声明产品变量时,我遇到了以下错误:Cannot subscript a value of type '[Product]' with an index of type 'UICollectionViewCell'【参考方案2】:

你忘了传product,换成传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
    

并在ProductDetailVC 更新用户界面

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

【讨论】:

谢谢。我的segue没有被触发。我不确定为什么?我确认我有一个带有正确标识符的故事板segue。 你确定你已经连接了单元和视图控制器的 segue 选择 segue 它将在两个视图中显示连接的元素 我已将 segue 连接到 viewController。我现在将它切换到单元格。 如果你想从视图中触发,那么你应该使用带有self.performsegue方法的collectionview的didlselect委托【参考方案3】:

在您的 ProductDetailVC 中,永远不会调用 updateView() 方法。您应该在 viewdidLoad 中调用它。 ;)

class ProductDetailVC: UIViewController 

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

var product: Product?

override func viewDidLoad() 
    super.viewDidLoad()
    updateView() // <-- This is what you missed!


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




此外,如果您的转场从未被触发,请确保它在情节提要中从单元格模板设置为 ProductDetailVC,并确保情节提要中的转场标识符设置为 ProductDetailVC(区分大小写)。

最后,在您的 prepareForSegue 方法中,您没有使用最后一个变量(让 product = ...),您应该将它传递给 productDetailVC。

干杯,

【讨论】:

天哪,真尴尬。我更新了它,但我确实认为我的 prepareForSegue 方法有问题。 segue 永远不会被触发。 是的,我的 segue 绑定到 VC,而不是单元格。

以上是关于无法将数据从集合视图传递到 Xcode 中的详细视图的主要内容,如果未能解决你的问题,请参考以下文章

将信息从一个集合视图传递到另一个更详细的集合视图的最佳方法是啥

Laravel 将数据从 ajax 传递到位于单独文件中的模态视图,导致模态视图无法呈现

如何将数据从集合视图传递到表视图类?

将数据从集合视图传递到表视图

将 Firebase 数据从一个视图控制器传递到详细视图控制器

将数据从集合视图单元格移动到新的集合视图单元格