首页 > 解决方案 > 使用 CollectionViewCell 中的按钮将数据从 collectionview Cell 解析到新的 viewController

问题描述

我有一个collectionView,我正在使用我在类中创建的数组填充它。collectionView 可以工作,但问题是当我想使用 collectionViewCell 中的按钮将特定数据从该单元格解析到 viewController 时。

我正在尝试做的一个示例是,如果我按下单元格中的按钮以获取我想要转到下一个 viewController 的问题图像,并且我希望该 viewController 的图像成为问题图像,也许我将来会添加一些其他的对应的数据。

我已经查看了这个站点和其他站点上的其他答案,这让我走到了这一步,但是我找不到任何东西来解决 collectionView 的这个问题。我知道它类似于 tableView,但是当我尝试基于 tableView 更改它时,它似乎对我不起作用。

这是第一个和第二个视图的图像

这是打开的视图,collectionview 和 cell 所在的位置

这是我要解析数据的视图

这是我创建的类:

import Foundation
import UIKit

class Information {

var image = ""
var button = ""
var infoOne = ""
var infoTwo = ""
var price = ""

init(image: String, button: String, infoOne: String, infoTwo: String, price: String) {
    self.image = image
    self.button = button
    self.infoOne = infoOne
    self.infoTwo = infoTwo
    self.price = price
}

//MARK: Carousel Data

static func createData() -> [Information] {
    return [
        Information(image:  "question", button: "Buy One", infoOne: "First Data", infoTwo: "Second Data", price: "10"),
        Information(image: "exclamation", button: "Buy Two", infoOne: "First Data", infoTwo: "Second Data", price: "20"),
        Information(image: "period", button: "Buy Three", infoOne: "First Data", infoTwo: "Second Data", price: "30"),
        Information(image: "all", button: "Buy Four", infoOne: "First Data", infoTwo: "Second Data", price: "40")
    ]
   }
}

这个数组在填充 collectionViewCell 时工作得很好。

这是 collectionViewCell

import UIKit

class InfoCollectionViewCell: UICollectionViewCell {

var infomation: Information! {
    didSet {
        updateUI()
    }
}

var addBtnAction : (()-> ())?

@IBOutlet weak var infoImage: UIImageView!

@IBOutlet weak var infoLblOne: UILabel!

@IBOutlet weak var infoLblTwo: UILabel!

@IBOutlet weak var priceLbl: UILabel!

@IBOutlet weak var buyBtn: UIButton!

fileprivate func updateUI() {
    infoImage.image! = UIImage(named: infomation.image)!
    infoLblOne.text = infomation.infoOne
    infoLblTwo.text = infomation.infoTwo
    priceLbl.text = infomation.price
    buyBtn.setTitle(infomation.button, for: .normal)
}

@IBAction func buyBtnPressed(_ sender: Any) {
    print("INFORMATION: \(infomation.image)")
    addBtnAction?()
}

override func layoutSubviews() {
    super.layoutSubviews()
    self.layer.cornerRadius = 5.0
    self.clipsToBounds = true
  }
}

这是视图控制器:

import UIKit

class ViewController: UIViewController {

let collectionViewCellId: String = "carouselCollectionCell"
@IBOutlet weak var collectionView: UICollectionView!

fileprivate var information = Information.createData()

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

}

extension ViewController: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {

    func numberOfSections(in collectionView: UICollectionView) -> Int {
    return 1
}

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

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "infoCell", for: indexPath) as! InfoCollectionViewCell
    cell.addBtnAction = {
        self.performSegue(withIdentifier: "mainSegue", sender: self)
    }
    cell.infomation = self.information[indexPath.item]
    return cell
}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "mainSegue" {
        let nxtVC = segue.destination as? DetailViewController
        let cell = sender as! InfoCollectionViewCell
        let myIndexPath = self.collectionView.indexPath(for: cell)
        nxtVC?.infomation = information[(myIndexPath?.item)!]
    }
}
}

因此,当我运行该应用程序时,一切都很好,直到我按下按钮来搜索和解析数据。该应用程序崩溃,这就是它所说的原因:

这是输出控制台中的内容:

无法将“carousel.ViewController”(0x107992178)类型的值转换为“carousel.InfoCollectionViewCell”(0x107991f98)。2018-09-28 21:22:52.116698-0400 carousel [1573:38999] 无法将“carousel.ViewController”(0x107992178)类型的值转换为“carousel.InfoCollectionViewCell”(0x107991f98)。(lldb)

如果可能的话,我宁愿保留按钮,但如果不可能,我会改变它。我不确定我做错了什么。如果还有什么我可以帮助的,请告诉我。非常感谢。

编辑:

似乎我忘了包含一个重要的视图,即另一个视图控制器的视图。

线程 1:致命错误:在展开可选值时意外发现 nil

这是我坚持的观点:

import UIKit

class DetailViewController: UIViewController {


@IBOutlet weak var infoImage: UIImageView!

@IBOutlet weak var dataTxtView: UITextView!

var testingImage: UIImage = UIImage()

var infomation: Information! {
    didSet {
        updateUI()

    }
}



override func viewDidLoad() {
    super.viewDidLoad()


}

fileprivate func updateUI() {


    let images = UIImage(named: infomation.image)
    infoImage.image = images

    print("Image: \(infomation.image)")

    }
}

在 updateUI 函数中,我尝试使 infoImage 与 infomation.image 相同,但它崩溃并指出:

线程 1:致命错误:在展开可选值时意外发现 nil

这对我来说没有多大意义,因为我试图打印 infomation.image 的字符串是什么,并且它起作用了,但是当我尝试将它作为图像放置时,它似乎崩溃了。再次感谢你

编辑2:

我弄清楚我做错了什么。似乎我一直在尝试使用可选字符串。我如何修复它是我更改了我制作的类,而不是字符串并将其转换为图像,它已经是图像。我还尝试创建一个 if let 语句来删除可选项。

这就是主 ViewController 中 prepareForSegue 的样子

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "mainSegue" {
        let nxtVC = segue.destination as? DetailViewController

        let cell = sender as? InfoCollectionViewCell
        let myIndexPath = self.collectionView.indexPath(for: cell!)

        if let indexPath = myIndexPath {

            nxtVC?.infomation = information[indexPath.row]

        }

    }
}

这是 viewDidLoad 的样子:

 override func viewDidLoad() {
    super.viewDidLoad()
    print("***********TESTINGIMAGE: \(infomation.image!)***********")

    infoImage.image = infomation.image!

}

我知道我正在用 ! 但我不知道如何删除可选的。感谢您的帮助。

标签: swiftuicollectionviewuicollectionviewcell

解决方案


问题是您假设senderinprepare是单元格的一个实例,但您的调用performSegue是作为发送者传递self的。但self在这种情况下是视图控制器,而不是单元格。

解决方案是通过单元格而不是self.

cell.addBtnAction = {
    self.performSegue(withIdentifier: "mainSegue", sender: cell)
}

推荐阅读