Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/103.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 在视图控制器之间传递数据会产生零_Ios_Swift_Xcode_Viewcontroller - Fatal编程技术网

Ios 在视图控制器之间传递数据会产生零

Ios 在视图控制器之间传递数据会产生零,ios,swift,xcode,viewcontroller,Ios,Swift,Xcode,Viewcontroller,我是一名新的程序员,在控制器之间传递数据时遇到了困难,我知道这些论坛会问这个问题,但上传的代码比我的复杂得多,我很难理解,所以我会上传我写的几行代码。我想允许两名玩家在我的应用程序中输入他们的名字,然后单击开始游戏。当按下“开始游戏”按钮时,会将他们带到一个新的视图控制器,该控制器的名称类似于Joe Bloggs vs John Doe,如果我将变量设置为全局变量,我可以实现这一点,但我的理解是,这是一种糟糕的做法,因此当我尝试编写相同的代码,将变量保留在视图控制器中时,每次都会通过nil,我不

我是一名新的程序员,在控制器之间传递数据时遇到了困难,我知道这些论坛会问这个问题,但上传的代码比我的复杂得多,我很难理解,所以我会上传我写的几行代码。我想允许两名玩家在我的应用程序中输入他们的名字,然后单击开始游戏。当按下“开始游戏”按钮时,会将他们带到一个新的视图控制器,该控制器的名称类似于Joe Bloggs vs John Doe,如果我将变量设置为全局变量,我可以实现这一点,但我的理解是,这是一种糟糕的做法,因此当我尝试编写相同的代码,将变量保留在视图控制器中时,每次都会通过nil,我不确定我做错了什么?这是我的几行代码,我希望有人能回答我做错了什么

视图控制器:

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

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

    }

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

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

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

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

    }

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

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

在加载控制器的视图之前,您的插座不会初始化。然而,赛格发生在这之前


最好的解决方案是将两个字符串属性放入
GameViewController
中,并使用这些属性从第一个控制器接收数据。然后,在
viewdiload
中更新标签文本。您不应该直接从另一个视图控制器设置标签文本,而是在
gameviewdiload
中创建变量来存储标签文本,在segue中更改这些变量,然后在目标控制器的
viewdiload
方法中更改标签。请参阅下面的代码

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中:

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

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

    }

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

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

在初始化控制器之前,不能设置
@IBOutlets
的属性。 您需要存储像
String这样的值在第二视图控制器中。和init
@IBOutlets
,例如在
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.
    }
}
ViewController
中的
prepare

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

希望有帮助

您检查过文本字段是否正确映射到变量了吗?如果在按钮回调之前调用了
prepare(for:sender:)
,怎么办?因为执行
destinationVC.playeron.text=playeroname
playeron
nil
。换句话说,
IBOulet
尚未加载。创建一个
String
属性,该属性将保存
playername
值。在
viewdiload()
上,在Objective-C中将
playerne.text
设置为它。但原因相同:或