2017-06-21 4 views
0

私は新しいプログラマで、コントローラ間でデータを渡すのに苦労しています。この質問はこのフォーラムで尋ねられますが、アップロードされたコードは私のものと比べてはるかに複雑で、それは私が書いた私の数行をアップロードするでしょう。 2人のプレイヤーが自分の名前を自分のアプリに入力して、ゲームを開始することを許可します。ゲームの開始ボタンが押されると、Joe Bloggs vs John Doeのような名前を持つ新しいView Controllerに移動します。私は変数をグローバルにしますが、私の理解は悪い練習です。同じコードを書いて、View Controller内の変数を毎回渡すことなく、何が間違っているのか分かりませんか?ここで私の間違ったことを誰かが答えることができるように私のコードのいくつかの行ですか?View Controller間でデータを渡すと、nilが生成される

のViewController:

import UIKit 

class ViewController: UIViewController { 

    var playerOneName: String! 
    var playerTwoName: String! 

    @IBOutlet weak var playerOneTextField: UITextField! 
    @IBOutlet weak var playerTwoTextField: UITextField! 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     // Do any additional setup after loading the view, typically from a nib. 
    } 

    @IBAction func startGameButton(_ sender: Any) { 

     playerOneName = playerOneTextField.text! 
     playerTwoName = playerTwoTextField.text! 

    } 

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 
     if segue.identifier == "segue" { 

      let destinationVC = segue.destination as! GameViewController 
      destinationVC.playerOne.text = playerOneName 
      destinationVC.playerTwo.text = playerTwoName 
     } 
    } 

} 

GameViewController:あなたのコントローラのビューがロードされるまで、あなたの出口は初期化されません

import UIKit 

class GameViewController: UIViewController { 

    @IBOutlet weak var playerOne: UILabel! 
    @IBOutlet weak var playerTwo: UILabel! 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     // Do any additional setup after loading the view. 

    } 

} 
+0

はあなたが点検したお役に立てば幸いですか!ボタンのコールバックの前に 'prepare(for:sender:)'が呼び出されたらどうなるでしょうか? – gskbyte

+0

'destinationVC.playerOne.text = playerOneName'を実行すると、' playerOne'は 'nil'です。つまり、 'IBOulet'はまだロードされていません。 'playerOneName'値を保持する' String'プロパティを作成します。 'viewDidLoad()'に 'playerOne.text'を設定します。 – Larme

+0

Objective-Cでは、理由は同じです:https://stackoverflow.com/questions/18137073/set-uitextfield-text-property-in-prepareforsegueまたはhttps://stackoverflow.com/questions/9576177/how-ユーラベル・オブ・ア・セグの価値を生み出すことができます – Larme

答えて

0

。しかし、その前にsegueが発生します。

最良の解決策は、文字列プロパティのいくつかをGameViewControllerに入れ、それらを使って最初のコントローラからデータを受け取ることです。次に、ラベルテキストをviewDidLoadに更新します。

1

あなたは別のビューコントローラから直接、ラベルのテキストを設定し、しかし、ラベルのテキストを格納セグエでこれらの変数を変更してから先コントローラのviewDidLoad方法でラベルを変更するGameViewControllerで変数を作成しないでください。下記のコードを参照してください。

class GameViewController: UIViewController { 

    @IBOutlet weak var playerOne: UILabel! 
    @IBOutlet weak var playerTwo: UILabel! 

    var playerOneName:String? 
    var playerTwoName:String? 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     playerOne.text = playerOneName 
     playerTwo.text = playerTwoName 
     // Do any additional setup after loading the view. 

    } 

} 

とのViewControllerで:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 
     if segue.identifier == "segue" { 

      let destinationVC = segue.destination as! GameViewController 
      destinationVC.playerOneName = playerOneName 
      destinationVC.playerTwoName = playerTwoName 
     } 
    } 
2

あなたのコントローラが初期化される前に、あなたは@IBOutletsのプロパティを設定することはできません。 String!のような値を2番目のビューコントローラに格納する必要があります。そして@IBOutletsviewDidLoadメソッドで初期化します。これに

変更GameViewControllerコード:

import UIKit 

class GameViewController: UIViewController { 
    @IBOutlet weak var playerOne: UILabel! 
    var playerOneName: String!  

    @IBOutlet weak var playerTwo: UILabel! 
    var playerTwoName: String! 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     playerOne.text = playerOneName 
     playerTwo.text = playerTextName 
     // Do any additional setup after loading the view. 
    } 
} 

そしてprepareViewController中:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 
    if segue.identifier == "segue" { 
     let destinationVC = segue.destination as! GameViewController 
     destinationVC.playerOneName = playerOneName 
     destinationVC.playerTwoName = playerTwoName 
    } 
} 

は、それがテキストフィールドが正しく変数にマッピングされている場合

関連する問題