视图控制器之间传递数据产生零
问题描述:
我是一个新的程序员,并在控制器之间传递数据挣扎,我知道这些问题在这些论坛中被问到,但上传的代码比我的复杂得多,我很难理解它会上传我写的几行。我想让两名玩家在我的应用中输入他们的名字,然后点击开始游戏。当开始游戏按钮被按下时,它将它们带到一个新的视图控制器,它的名字就像这样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.
}
}
答
,直到你的控制器的风景被你的店铺没有得到初始化。然而,在这之前就发生了这种情况。
最好的解决方案是将几个字符串属性放入GameViewController
并使用它们接收来自第一个控制器的数据。然后,更新viewDidLoad
中的标签文字。
答
你不应该直接从另一个视图控制器设置标签的文本,但创建变量在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
}
}
答
你控制器初始化之前,不能设置的@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.
}
}
而且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
}
}
希望它可以帮助
你检查,如果文本字段被正确地映射到变量?在按钮回调之前调用'prepare(for:sender:)'会怎么样? – gskbyte
因为当您执行destinationVC.playerOne.text = playerOneName时,'playerOne'是'nil'。换句话说,'IBOulet'尚未加载。创建一个将保存'playerOneName'值的'String'属性。在'viewDidLoad()'设置'playerOne.text'。 – Larme
在Objective-C中,但原因是一样的:https://stackoverflow.com/questions/18137073/set-uitextfield-text-property-in-prepareforsegue或https://stackoverflow.com/questions/9576177/how-可以-I-设定的值对的一-的UILabel-以下-A-SEGUE – Larme