在视图控制器之间传递数据会产生 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:)
会怎样?
因为playerOne
是nil
当你做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 [重复]的主要内容,如果未能解决你的问题,请参考以下文章
在视图控制器之间传递 iOS 10 Segue 中的数据 [重复]
在视图控制器之间的 NSString 中传递数据 - 目标 C [重复]