【问题标题】:Passing data between view controllers produces nil [duplicate]在视图控制器之间传递数据会产生 nil [重复]
【发布时间】: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 中,但原因是一样的:stackoverflow.com/questions/18137073/…stackoverflow.com/questions/9576177/…

标签: ios swift xcode viewcontroller


【解决方案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 中的标签文本。

      【讨论】:

        猜你喜欢
        • 2021-03-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-09
        相关资源
        最近更新 更多