在视图控制器之间传递数据会产生 nil [重复]

Posted

技术标签:

【中文标题】在视图控制器之间传递数据会产生 nil [重复]【英文标题】:Passing data between view controllers produces nil [duplicate] 【发布时间】:2017-06-21 12:30:54 【问题描述】:

我是一名新程序员,正在努力在控制器之间传递数据,我知道在这些论坛中提出了这个问题,但上传的代码与我的相比要复杂得多,我很难理解它,所以将上传我的几行代码我写过。我想让两个玩家在我的应用程序中输入他们的名字,然后单击开始游戏。当按下开始游戏按钮时,它会将它们带到一个新的视图控制器,其名称类似于 Joe Bloggs vs John Doe,如果我将变量设为全局变量,我可以实现这一点,但我的理解是这是不好的做法,所以当我尝试和编写相同的代码,将变量保存在 View Controller 中,它每次都通过 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.

    


【问题讨论】:

您是否检查过文本字段是否正确映射到变量?如果在按钮回调之前调用prepare(for:sender:) 会怎样? 因为playerOnenil 当你做destinationVC.playerOne.text = playerOneName。换句话说,IBOulet 尚未加载。创建一个String 属性,该属性将保存playerOneName 值。在viewDidLoad() 上将playerOne.text 设置为它。 在 Objective-C 中,但原因是一样的:***.com/questions/18137073/… 或 ***.com/questions/9576177/… 【参考方案1】:

您不能在控制器初始化之前设置@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
    

希望对你有帮助

【讨论】:

【参考方案2】:

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

    


在 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
        
    

【讨论】:

【参考方案3】:

在加载控制器的视图之前,您的插座不会被初始化。然而,转场发生在此之前。

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

【讨论】:

以上是关于在视图控制器之间传递数据会产生 nil [重复]的主要内容,如果未能解决你的问题,请参考以下文章

在 Swift 中的视图控制器之间传递数据

在视图控制器之间传递数据而不使用 segues [重复]

在视图控制器之间传递 iOS 10 Segue 中的数据 [重复]

在视图控制器之间的 NSString 中传递数据 - 目标 C [重复]

如何在视图控制器之间传递数据而不在 ios 中使用 segue?

在视图控制器之间传递NSString中的数据 - 目标C [重复]