所以这是来自VC1的代码并将数据传递给VC2。
override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
selectedArtist = artists[indexPath.item]
performSegue(withIdentifier: "artistToArtSegue", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "artistToArtSegue" {
let artCollectionController = ArtCollectionController()
artCollectionController.artist = selectedArtist
artCollectionController.selectedArtist = selectedArtist
}
}
VC2中的这些代码将打印数据
class ArtCollectionController: UICollectionViewController {
var artist = Artist() {
didSet{
print(artist.artistId ?? "did not work")
print(artist.name ?? "what name?")
}
}
var selectedArtist = Artist()
但是当我在VC2中使用以下测试代码中的变量时。他们返回零。
func fetchArtForArtist() {
guard let artistId = selectedArtist.artistId else {return}
print(artistId)
let fanRef = FIRDatabase.database().reference().child("art_ref").child(artistId)
fanRef.observeSingleEvent(of: .childAdded, with: { (snapshot) in
let artId = snapshot.key
print(artId)
// let dataRef = FIRDatabase.database().reference().child(artId)
// dataRef.observe(.value, with: { (snapshot) in
// let dictionary = snapshot.value as? [String: AnyObject]
// //let art =
// }, withCancel: nil)
}, withCancel: nil)
}
@IBAction func testButton(_ sender: UIBarButtonItem) {
print(selectedArtist.name ?? "no name")
print(12345)
}
override func viewDidAppear(_ animated: Bool) {
selectedArtist = artist
print(artist.name ?? "non")
print(selectedArtist.artistId ?? "no id")
}
override func viewDidLoad() {
super.viewDidLoad()
fetchArtForArtist()
selectedArtist = artist
print(artist.name ?? "non")
print(selectedArtist.artistId ?? "no id")
}
我在storyBoard中这样做。我甚至使用2个vars看看是否有区别。我不明白为什么数据成功传递给VC2到几个变量,但是当使用变量时它返回一个nil。请帮忙。
答案 0 :(得分:3)
其他答案都很好,但我更喜欢略有不同的方法:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
switch segue.destination {
case let artCollectionController as ArtCollectionController:
artCollectionController.artist = selectedArtist
artCollectionController.selectedArtist = selectedArtist
case let otherViewController as OtherViewController:
//Code for some other case
}
}
通过使用switch语句,您有prepareForSegue
可以干净地处理多个不同的段。
case let
构造是一个很酷的技巧,只有在交换机中的变量可以是所需类型的情况下才执行该情况。如果可以强制转换,则会创建所需类型的局部变量。
我更喜欢根据目标视图控制器的类来决定要执行的代码,因为它比使用segue标识符更不易碎。如果您忘记设置segue标识符,或稍后将第二个segue添加到同一类型的视图控制器,或者在标识符的名称中输入错误,则该代码将无法正常工作。但是,如果类名中有拼写错误,则编译器会抛出错误。
答案 1 :(得分:2)
因为您在artist
的新实例上设置了ArtCollectionController
属性,该实例在prepareForSegue
函数退出时被销毁:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "artistToArtSegue" {
let artCollectionController = ArtCollectionController() // created
artCollectionController.artist = selectedArtist
artCollectionController.selectedArtist = selectedArtist
// destroyed here
}
}
请改为尝试:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "artistToArtSegue",
let artCollectionController = segue.destination as? ArtCollectionController
{
artCollectionController.artist = selectedArtist
artCollectionController.selectedArtist = selectedArtist
}
}
答案 2 :(得分:1)
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "artistToArtSegue" {
let artCollectionController = segue.destination as! ArtCollectionController
artCollectionController.artist = selectedArtist
artCollectionController.selectedArtist = selectedArtist
}
}
试试这个,你又创建了一个ArtCollectionController
而不是传递数据来实现一个