2017-06-21 131 views
0

我是一个新的程序员,并在控制器之间传递数据挣扎,我知道这些问题在这些论坛中被问到,但上传的代码比我的复杂得多,我很难理解它会上传我写的几行。我想让两名玩家在我的应用中输入他们的名字,然后点击开始游戏。当开始游戏按钮被按下时,它将它们带到一个新的视图控制器,它的名字就像这样Joe Bloggs vs John Doe,我可以实现这个如果我让我的变量是全局的,但我的理解是这是不好的做法,所以当我尝试编写相同的代码,保持视图控制器内的变量它每次都通过零,我不确定我做错了什么?这是我的几行代码,我希望有人能回答我做错了什么?视图控制器之间传递数据产生零

的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-可以-I-设定的值对的一-的UILabel-以下-A-SEGUE – Larme

回答

0

,直到你的控制器的风景被你的店铺没有得到初始化。然而,在这之前就发生了这种情况。

最好的解决方案是将几个字符串属性放入GameViewController并使用它们接收来自第一个控制器的数据。然后,更新viewDidLoad中的标签文字。

1

你不应该直接从另一个视图控制器设置标签的文本,但创建变量在GameViewController存储标签文本,更改SEGUE这些变量,然后更改标签在你的目标控制器的viewDidLoad方法。见下面的代码。

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. 

    } 

} 

并在视图控制器:

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!这样的值。例如,与他们在viewDidLoad方法中。

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

希望它可以帮助

相关问题