在视图控制器之间传递数据将产生 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.
    }
}

在初始化控制器之前,无法设置@IBOutlets的属性。您需要在第二个视图控制器中存储String!等值。例如,viewDidLoad方法中对它们进行初始化@IBOutlets

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

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

希望对你有帮助

不应直接从另一个视图控制器设置标签的文本,而是在 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
        }
    }

在加载控制器的视图之前,不会初始化插座。 但是,续集发生在这之前。

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

最新更新