Reputation: 519
Suppose I have three view controllers in a Main.storyboard. Two of the three, vc_login
and vc_studyDesc
load the other view controller using a UIButton with 'present modally' option.
The other one vc_signup
has a UIButton, which may go back to the previous controller. To implement this, I used the following methods:
vc_studyDesc
has an identifier of studyDesc
; I let it pass its identifier to vc_signup
. In the same way, vc_login
has login
as an identifier.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if sender as! UIButton == qnaSignUp {
let signup = segue.destinationViewController as! vc_signup
signup.latestVC = "studyDesc"}}
This one is in the UIViewController
class for vc_signup
. By referencing a string latestVC
, the method determines which VC to move on.
@IBAction func backBtnClick(sender: UIButton) {
print("latestVS: \(latestVC)")
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier(latestVC)
vc.modalTransitionStyle = UIModalTransitionStyle.CrossDissolve
print("check check")
self.presentViewController(vc, animated: true, completion: nil)}
The problem I have is that the app gets terminated when vc_studyDesc
is called by vc_signup
. I found that this is because I missed a significant variable which must be loaded in vc_signup
.
vc_studyDesc
has some data to be referenced from Firebase when it is loaded. I did this by loading a variable postID
from the prior vc to vc_studyDesc
; which is vc_list
.
So I just saved postID
using NSUserdefaults.standardUserDefaults()
. It is solved but I'm wondering if there's any way to pass data using the way I used in vc_signup
.
As far as I see, I cannot find any way to pass the data into vc_studyDesc.swift
; for the vc is chosen by its identifier..
Can I pass the variable I want in the way I want?? And adding tags would be appreciated!
Upvotes: 0
Views: 323
Reputation: 2856
So there are a couple problems with this design.
When you instantiate a viewController you are creating a new instance of that class, and presenting it adds it to the stack. Think of the stack like a deck of cards, you start with one card and then add or remove them, the top card being the visible vc. When you are going back to studyDesc you are instantiating and presenting it so you will have 3 VCs in your stack, of which two are studyDesc (the one you started with and the one you add when you try to go back)
To remove a VC from the stack you can use
dismissViewController(animated: true, completion: nil)
or if you have the VCs in a navigation controller you can use
popViewControllerController(animated: true, completion: nil)
in terms of passing information between viewControllers, if the info is in the VC you use to present your new controller you can use prepareForSegue like you already have. To pass information back you should use a delegate pattern. So to implement a delegate pattern in this case you would do the following:
Declare a protocol (not inside your classes, above there but below your import's)
protocol SignUpDelegate {
signInCompleted(infoToPass: AnyObject)
}
Then have your studyDesc class conform to this protocol and implement the function signInCompleted
StudyDescVC: UIViewController, SignUpDelegate {
func signInCompleted(infoToPass: AnyObject) {
// do what you want with the info here
}
}
Then in your signUpVc add a var delegate (which will be used to call the signInCompeleted function)
class SignInVC: UIViewController {
var delegate: SignUpDelegate!
func finishedSigningIn() {
delegate.signInCompleted(infoToPass: //yourinfo)
self.dismissViewControllerAnimated(true, completion: nil)
}
And then in your prepareForSegue set the delegate
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if sender as! UIButton == qnaSignUp {
let signup = segue.destinationViewController as! vc_signup
signup.delegate = self
}
}
Upvotes: 1
Reputation: 180
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier(latestVC) as! YOUR_VIEW_CONTROLLER_NAME
vc.modalTransitionStyle = UIModalTransitionStyle.CrossDissolve
vc.name = "Andrew"
print("check check")
self.presentViewController(vc, animated: true, completion: nil)
//set a variale or property to your viewController
class YOUR_VIEW_CONTROLLER_NAME: UIViewController {
var name: String?
}
Upvotes: 0