Swift 3将数据从一个ViewController传递到另一个ViewController

我是IOS编程的新手,并不知道我在问什么,但我会尽力解释

我正在使用Firebase身份validation,然后我想采取的UID,并将其传递给一个不同的VC我得到的问题我无法得到var userID打印出来的IBAction这边是我到目前为止,任何指针会得到好的欢呼家伙

 @IBAction func creatAccountPressed(_ sender: Any) { if let email = emailTextField.text, let password = passwordTextField.text, let name = nameTextField.text { Auth.auth().createUser(withEmail: email, password: password, completion: { user, error in if let firebaseError = error { print(firebaseError.localizedDescription) } let userID = user!.uid let userEmail: String = self.emailTextField.text! let fullName: String = self.nameTextField.text! self.ref.child("users").child(userID).setValue(["Email": userEmail, "Name": fullName]) self.userID1 = user!.uid as! String }) print(self.userID1) presentLoggedInScreen() } } func presentLoggedInScreen() { let stroyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil) let loggedInVC: LoggedInVCViewController = stroyboard.instantiateViewController(withIdentifier: "loggedInVC") as! LoggedInVCViewController self.present(loggedInVC, animated: true, completion: nil) } 

一种将信息从一个VC传递到另一个的简单方法是通过initiliazer,或者通过在提交第二个VC之前设置的variables。

既然你是新手,现在就尝试一下variables方法,如果说,你传递一个string:

 class LoggedInVCViewController : UIViewController { var info : String? { didSet { if let newInfo = self.info { //do what ever you need to do here } } } override viewDidLoad() { super.viewDidLoad() } } func presentLoggedInScreen(yourInfo: String) { let stroyboard:UIStoryboard = UIStoryboard(name: "Main", bundle: nil) let loggedInVC:LoggedInVCViewController = storyboard.instantiateViewController(withIdentifier: "loggedInVC") as! LoggedInVCViewController loggedInVC.info = yourInfo self.present(loggedInVC, animated: true, completion: nil) } 

请注意,您可以随时使用任何其他可变级别的王级info 。 你也可以编程你的VC在属性的get括号内执行一些方法,根据信息的内容填充一些字段,加载特定的UI等。

另一个有用的方法是去初始化路线,但不幸的是,你不能用它与故事板笔尖(伤心,我知道,但这篇文章很好地),但它仍然有用,只要你会觉得足够舒适,初始化和deviseVC的程序化如果你愿意,我会尽快学习)。

你为你的VC传递一个自定义初始化方法的variables:

 class LoggedInVCViewController : UIViewController { var info : Any? { get { if let this = self.info { return this } else { return nil } } set { if let new = newValue { // } } } init(info: Any?) { //This first line is key, it also calls viewDidLoad() internally, so don't re-write viewDidLoad() here!! super.init(nibName: nil, bundle: nil) if let newInfo = info { //here we check info for whatever you pass to it self.info = newInfo } } override func viewDidLoad() { super.viewDidLoad() } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } } 

所以你会使用的是:

 func presentLoggedInScreen(yourInfo: String) { let loggedInVC = LoggedInVCViewController(info: yourInfo) self.present(loggedInVC, animated: true, completion: nil) } 

显然,如前所述,这种方法不能与Storyboard一起使用,但是非常有用,而且我相信你可以看到,它更加紧凑。

我build议你熟悉Swift属性的文档,以及一些博客技巧,如这一个 。 过一段时间你可以变得非常有创意。

为了学习更多的程序化方法,我强烈推荐这个YouTube频道: 让我们来构build这个应用程序 ,我个人认为没有find一个更好的Swift编程的参考点。

不要犹豫,问问题!

UPDATE

你的IBAction应该是这样的:

 @IBAction func creatAccountPressed(_ sender: Any) { if let email = emailTextField.text, let password = passwordTextField.text, let name = nameTextField.text { Auth.auth().createUser(withEmail: email, password: password, completion: { user, error in if let firebaseError = error { print(firebaseError.localizedDescription) } let userID = user!.uid let userEmail: String = self.emailTextField.text! let fullName: String = self.nameTextField.text! self.ref.child("users").child(userID).setValue(["Email": userEmail, "Name": fullName]) self.userID1 = user!.uid as! String print(self.userID1) presentLoggedInScreen(yourInfo: self.userID1) }) } } 

 print(self.userID1) presentLoggedInScreen() 

在完成块内。 目前在完成块完成之前 ,这些线几乎肯定会发生因为在所需的networking调用返回后执行块。

一定要将presentLoggedInScreen()包装在调度到主线程的块中,因为它触及了UI,并且所有的 UI调用必须由主线程调用。

 DispatchQueue.main.async { presentLoggedInScreen() } 

这将使得presentLoggedInScreen()在分配给userID1的值之后执行,从而允许您将值传递给传入的视图控制器(当然,假设传入的VC具有适当的variables来传递userID1 )。

就像是:

 loggedInVC.userID = self.userID1 

在您介绍VC之前。