2017-03-19 12 views
0

これはVC1のコードとVC2のデータです。私はVC2でこれらの次のテストコードで変数を使用する場合、ここでVC2でSwift 3、正常にデータを渡しましたが、使用するとvarはnilを返します。

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

これらのコードは、

class ArtCollectionController: UICollectionViewController { 

    var artist = Artist() { 
     didSet{ 
      print(artist.artistId ?? "did not work") 
      print(artist.name ?? "what name?") 
     } 
    } 
    var selectedArtist = Artist() 

データを印刷しますが。彼らは何も返さない。

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") 


    } 

ストーリーボードでこれをやっています。差があるかどうかを確認する2つのvarsを使用してもIm。私はデータが正常にVC2にいくつかの変数に渡された理由を理解していないが、変数が使用されているときにはnilを返します。助けてください。

答えて

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

あなたがprepareForSegue機能の終了時に破壊されるArtCollectionControllerの新しいインスタンスを、上artistプロパティを設定しているので、あなたが代わりに1

+0

あなたはロックスターの男です!迅速かつ無痛!前に私がどのようにしたのかは、プログラム的なアプローチのほうが多かったと思います。プログラム的な私の他のプロジェクトでも動作します。ありがとうございます! –

+1

@ReyCerioいいえ、投稿したコードは間違っていました。このビット: 'let artCollectionController = ArtCollectionController()'は、 'if'ステートメントの中括弧の中にのみ存在する' ArtCollectionController'の新しいインスタンスを作成します。画面には決して表示されず、表示しようとしている 'ArtCollectionController'とは何の関係もありません。 JuicyFruitのコードは、あなたが志望しているView Controllerにアクセスする方法です。 –

2

をセグエにデータを渡すのArtCollectionController 1以上を作成している、これを試してみてください:

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

ここでは、 'destination'の' 'let''が良い方法であるかどうか不明ですが、あなたの目的地は' DestinationViewControllerForIdentifier'でなければなりません。 – JuicyFruit

+0

あなたが動作していることが確かでない限り、強制的にキャストする( 'as!')ことは決して良い習慣ではありません。私はいくつかの不思議なクラッシュに出くわしました。これはその後のコードリビジョンで変更された識別子であることが判明しました –

+0

彼が最初に投稿したからといって、JuicyFruitの答えを答えとして受け入れます。あなたの答えは本質的に彼と同じですので、あなたの答えを+1します。私のvarがなぜデータを失うのかをよりよく理解できる 'segue.destination'を使用しなければならない理由を答えてくれます。再度、感謝します。 –

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文を使用することにより、あなたはきれいに複数の異なるseguesを処理するprepareForSegueを持っています。

case let構文は、スイッチの変数が目的のタイプに対応できる場合にのみそのケースを実行するクールなトリックです。 にキャストできる場合は、目的のタイプのローカル変数を作成します。

宛先ビューコントローラのクラスに基づいてどのコードを実行するかは、セグ識別子よりも壊れにくいため、決定することをお勧めします。 segue識別子を設定するのを忘れたり、後で同じタイプのView Controllerに2番目のSegueを追加したり、識別子の名前にタイプミスがあったりすると、そのコードは機能しません。ただし、クラス名にタイプミスがあると、コンパイラはエラーをスローします。

+0

これも素晴らしいです。私はこれを念頭に置いておきます。 –

関連する問題