swift - 使用 CollectionViewCell 中的按钮将数据从 collectionview Cell 解析到新的 viewController
问题描述
我有一个collectionView,我正在使用我在类中创建的数组填充它。collectionView 可以工作,但问题是当我想使用 collectionViewCell 中的按钮将特定数据从该单元格解析到 viewController 时。
我正在尝试做的一个示例是,如果我按下单元格中的按钮以获取我想要转到下一个 viewController 的问题图像,并且我希望该 viewController 的图像成为问题图像,也许我将来会添加一些其他的对应的数据。
我已经查看了这个站点和其他站点上的其他答案,这让我走到了这一步,但是我找不到任何东西来解决 collectionView 的这个问题。我知道它类似于 tableView,但是当我尝试基于 tableView 更改它时,它似乎对我不起作用。
这是第一个和第二个视图的图像
这是我创建的类:
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!
}
我知道我正在用 ! 但我不知道如何删除可选的。感谢您的帮助。
解决方案
问题是您假设sender
inprepare
是单元格的一个实例,但您的调用performSegue
是作为发送者传递self
的。但self
在这种情况下是视图控制器,而不是单元格。
解决方案是通过单元格而不是self
.
cell.addBtnAction = {
self.performSegue(withIdentifier: "mainSegue", sender: cell)
}
推荐阅读
- android - 如何在 Android 中管理离线 Mongo 数据库
- ruby-on-rails - Rails:可以重构这个查询吗?
- php - 使用预定义常量和 parse_url 检测 URL 以定义常量。这是最好的方法吗?
- java - Camunda - 根据分配的组过滤任务列表
- excel - 被运行时错误“1004”难住:无法设置 PageSetup 类的 PrintTitleRows 属性
- reactjs - JEST + React 测试库:我应该在测试之前使用 beforeAll 渲染我的组件吗?
- android - Http 请求在 Flutter 中不返回任何内容,也不会抛出任何错误
- sql - 在解决这个关于在这个问题上应用“计数函数”的“数据比较”相关问题时,我得到的输出为零
- authentication - Cakephp 4.0 认证示例
- wordpress - 邮件未在联系表 7 提交中发送