在 Swift 4 中将数据从 CollectionView 传递到 DetailVC
Passing data from CollectionView to DetailVC in Swift 4
我的 CollectionView
应该将 class 模型传递给 DetailViewController
,但是当我点击一个单元格时,出现 nil 错误。
Fatal error: Unexpectedly found nil while implicitly unwrapping an
Optional value
CollectionViewController
以编程方式嵌入到 TabBarController
中。
集合视图
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return soundArray.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "SoundCell", for: indexPath) as? SoundCell {
let SoundClass = soundArray[indexPath.row]
cell.updateUI(SoundClass: SoundClass)
return cell
} else {
return UICollectionViewCell()
}
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
self.performSegue(withIdentifier: "seguetosound", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "seguetosound" {
if let detailVC = segue.destination as? DetailSecondVC
let sound = sender as? SoundClass {
detailVC.SoundClass = sound
}
}
详细视图控制器
class DetailSecondVC: UIViewController, UIWebViewDelegate {
private var _SoundClass: SoundClass!
var SoundClass: SoundClass {
get {
return _SoundClass
} set {
_SoundClass = newValue
}
}
你知道我在这里错过了什么吗?我用一个简单的白屏测试了 segue,它可以工作,但是当我尝试传递数据时,它失败了。
正确的做法是这样的。首先,弄清楚你想如何触发 segue。一种选择是,在 didSelect
中,在代码中触发 segue:
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
self.performSegue(withIdentifier: "seguetosound", sender: self)
}
但更好的是,完全删除 didSelectItemAt
并让情节提要中的转场来自单元格。这样,当用户点击单元格时,segue 会自动触发。
然后,在prepare
中找出选择的索引路径,并从模型中提取数据并将其传递给目标视图控制器(这可能无法编译,因为您的变量名是如此太糟糕了,我看不懂你的代码,但通常这是正确的方法):
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "DetailSecondVC" {
if let detailVC = segue.destination as? DetailSecondVC {
if let paths = collectionView?.indexPathsForSelectedItems {
let row = paths[0].row
detailVC.SoundClass = SoundClasss[row]
}
}
}
}
已编辑:我认为解决方案是从视图控制器而不是从单元格进行转场,但正如马特所说,从单元格转场是正确的,但我只需要删除 didSelectItemAt
我的 CollectionView
应该将 class 模型传递给 DetailViewController
,但是当我点击一个单元格时,出现 nil 错误。
Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value
CollectionViewController
以编程方式嵌入到 TabBarController
中。
集合视图
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return soundArray.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "SoundCell", for: indexPath) as? SoundCell {
let SoundClass = soundArray[indexPath.row]
cell.updateUI(SoundClass: SoundClass)
return cell
} else {
return UICollectionViewCell()
}
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
self.performSegue(withIdentifier: "seguetosound", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "seguetosound" {
if let detailVC = segue.destination as? DetailSecondVC
let sound = sender as? SoundClass {
detailVC.SoundClass = sound
}
}
详细视图控制器
class DetailSecondVC: UIViewController, UIWebViewDelegate {
private var _SoundClass: SoundClass!
var SoundClass: SoundClass {
get {
return _SoundClass
} set {
_SoundClass = newValue
}
}
你知道我在这里错过了什么吗?我用一个简单的白屏测试了 segue,它可以工作,但是当我尝试传递数据时,它失败了。
正确的做法是这样的。首先,弄清楚你想如何触发 segue。一种选择是,在 didSelect
中,在代码中触发 segue:
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
self.performSegue(withIdentifier: "seguetosound", sender: self)
}
但更好的是,完全删除 didSelectItemAt
并让情节提要中的转场来自单元格。这样,当用户点击单元格时,segue 会自动触发。
然后,在prepare
中找出选择的索引路径,并从模型中提取数据并将其传递给目标视图控制器(这可能无法编译,因为您的变量名是如此太糟糕了,我看不懂你的代码,但通常这是正确的方法):
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "DetailSecondVC" {
if let detailVC = segue.destination as? DetailSecondVC {
if let paths = collectionView?.indexPathsForSelectedItems {
let row = paths[0].row
detailVC.SoundClass = SoundClasss[row]
}
}
}
}
已编辑:我认为解决方案是从视图控制器而不是从单元格进行转场,但正如马特所说,从单元格转场是正确的,但我只需要删除 didSelectItemAt