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

时间:2017-07-05 20:14:05

标签: ios swift

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

我正在使用Firebase进行身份验证,然后我想将UID传递给另一个VC我遇到的问题我无法让var userID打印出IBAction的一面1}}这是我到目前为止的地方,任何指针都会得到很好的欢呼球员

@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)
}

2 个答案:

答案 0 :(得分:1)

将信息从一个VC传递到另一个VC的简单方法是通过initiliazer,或者通过在呈现第二个VC之前设置的变量。

由于你是新手,现在尝试使用变量方法,所以如果你正在传递一个字符串:

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括号内执行某些方法,根据info的内容填充一些字段,加载特定的UI等。

另一个有用的方法是进入初始化路线,但遗憾的是你不能将它与故事板笔尖一起使用(我知道很难过,但这个post很好地解决了这个问题)但是只要你感觉足够舒服它仍然有用以编程方式初始化和设计VC(如果你是我,我会尽快学习)。

您在VC的自定义intializer方法中传递变量:

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")
    }

}

所以你会使用is as:

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

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

我建议您熟悉文档的Swift Properties以及this one等一些博客提示。一段时间后你可以变得非常有创意。

为了学习更多程序化方法,我强烈推荐这个YouTube频道:Let's Build That App,我个人还没有找到更好的Swift编程方法的参考点。

不要犹豫提问!

<强>更新

您的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)


        })

    }
}

答案 1 :(得分:0)

print(self.userID1)

presentLoggedInScreen()

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

确保将presentLoggedInScreen()包装在一个块中,该块在触及UI时将其分派给主线程,并且所有 UI调用必须来自主线。

DispatchQueue.main.async {
  presentLoggedInScreen()
}

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

类似的东西:

loggedInVC.userID = self.userID1
在你出示VC之前