使用CollectionViewCell中的按钮将数据从collectionview单元解析到新的viewController

时间:2018-09-29 01:55:04

标签: swift uicollectionview uicollectionviewcell

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

我想要做的一个例子是,如果我按下问题图像单元格中的按钮,我想选择到下一个viewController,并且我希望那个viewController的图像成为问题图像,也许我就是未来添加与之对应的其他数据。

我已经查看了该站点和其他站点上的其他答案,这使我走了这么远,但是我找不到解决collectionView问题的任何方法。我知道它类似于tableView,但是当我尝试基于tableView对其进行更改时,它似乎对我不起作用。

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

This is the opening View and where the collectionview and cell is

This is the view I want to parse the data to

这是我创建的类:

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

这是viewController:

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字符串是什么,并且可以工作,但是当我尝试将其作为图像放置时,似乎崩溃了。 再次谢谢你

EDIT2:

我弄清楚我做错了什么。似乎我一直在尝试使用可选字符串。我如何解决的是,我更改了我制作的类,而不是字符串,并将其转换为图像,它已经是图像。我还尝试创建一个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!

}

我知道我正在用!展开图像!但我不知道如何删除可选的否则。 谢谢您的帮助。

1 个答案:

答案 0 :(得分:2)

问题在于您假设sender中的prepare是单元格的一个实例,但是您对performSegue的调用正在将self作为发送者。但是在这种情况下,self是视图控制器,而不是单元格。

解决方案是传递单元格而不是self

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