Having this methods:
//Metodo che verifica se proveniamo dal Profile controller o da un altro controller
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "accountSegue" {
self.DisattivaTutorialBtn.isHidden=true
IndietroBtn.isHidden=false
}else{
self.IndietroBtn.isHidden=true
self.DisattivaTutorialBtn.isHidden=false
}
}
I perform different actions basing on the segue's identifier.
Of course, this method isn't called anywhere (I understood that it is): how can I call it? It seems stupid but calling it as "self" method in "viewDidLoad" doesn't work.
To do that instead of performing your Segue on a button click in storyboard, create a segue from your viewcontroller to your other view controller. then when you want to go to the next view controller call below from your button click or any other action event.
self.performSegue(withIdentifier: "accountSegue", sender: self)
This will automatically call your prepareForSegue method and your if statement will execute.
If you are using manual segues in your Storyboard, you can perform the segue by calling self.performSegue(withIdentifier:sender:). See performSegue documentation.
If you are using segues whose type is not set to manual, when you click on the UI element to which the segue is linked in your Storyboard, prepare(for segue) will be called automatically by the system.
To perform Segue manually you need to attach the action
Following will help you go get the required thing done
performSegue(withIdentifier: "accountSegue", sender: nil)
Related
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
super.prepare(for: segue, sender: sender)
self.delegate = segue.destination as? MenuViewController
print("check_1", self.delegate)
}
#IBAction func openMenu(_ sender: Any) {
performSegue(withIdentifier: "openMenu", sender: sender)
print("check_2", self.delegate)
}
My main ViewController updates values while MenuViewController displays these values. Each time ViewController values are updated, it calls self.delegate.updateValues in MenuViewController. I transition between the two ViewControllers through buttons.
My problem is that it seems like the MenuViewController displayed is a different object than the one stored in self.delegate inside ViewController. Printing the check statements:
check_1 Optional(<Menu.MenuViewController: 0x10161ca10>)
check_2 Optional(<Menu.MenuViewController: 0x10161ca10>)
check_1 Optional(<Menu.MenuViewController: 0x10161dd10>)
May I ask how do I make sure only one instance of MenuViewController is created and stored in self.delegate?
When you add a segue to a storyboard, if you hook up the segue to a specific button/IBAction, you don't need to call performSegue manually, it will be automatically called for you.
You have 2 segues executed, since both the storyboard executes the segue and then you also do it from code by calling performSegue.
performSegue should only be used when your segue isn't directly hooked up to a UI event or if you need to conditionally perform a segue - such as when you have a login button, where depending on the network response, you might execute an error or a login segue.
I have two buttons - "Ok" and "Delete", and the "Ok" unwinds the segue to the last ViewController.
I want the "Delete" button to fire up the same unwind segue, but to do some action beforehand. (In my case, delete info from Firebase).
How can I combine both an action and unwind segue ? I tried calling PerformSegueWithIdentifier function but it didn't work.
Create a second unwind segue by control-dragging from your Delete button to the Exit icon. You can even use the existing #IBAction in your destination viewController. Give this segue an identifier (select the segue in the Document Outline view and set the identifier in the Attributes Inspector) such as "deleteSegue" and then in prepare(for:sender) check for the identifier and delete the info from Firebase.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "deleteSegue" {
// delete data from Firebase
}
}
Follow up question from the comments:
I want to perform an action BEFORE unwinding the segue - I want a
popup to ask the user if he really wants to delete the item. only
after that I want the item deleted and segue unwinded.
Instead of wiring the unwind segue from the Delete button, wire it from the viewController icon at the top of the VC to the Exit icon. Still give it the identifier and then call performSegue(withIdentifier: "deleteSegue", sender: self) when you want to perform the segue.
When I execute the line below, my destination view controller is not visually presented but there are no errors in the log:
performSegue (withIdentifier: "DetailsViewController", sender: self)
Let's step back from a problem. Imagine my successful setup: ViewController is loaded and upon some user action the above line would actually open a new DetailsViewController. I tested - everything works as expected - so I know it works.
But the problem presenting DetailsViewController begins when I decide to implement some third party framework by adding a CamViewController to my ViewController and perform segue upon element tap inside CamViewController, then delegate method passing this action back to ViewController from which I would open DetailsViewController. With this architecture setup I get no errors in a log but visually nothing is opening. No DetailsViewController ever presented.
A bit more details of architecture:
ViewController presents CamViewController with line self.present(camViewController, animated: true, completion: nil)
CamViewController implements a protocol to call some method on user action
ViewController conforms to CamViewController protocol and delegate method successfully runs on user action (log shows it is working)
Calling DetailsViewController with segue identifier is executed successfully performSegue (withIdentifier: "DetailsViewController", sender: self) but DetailsViewController is never displayed on screen.
This method below prints prepare for segue Optional("DetailsViewController") which sounds correct.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
print("prepare for segue \(segue.identifier)")
}
I also tried adding super.performSegue - no luck
First I would change your segue code to something more like this.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "DetailsViewController"){
print("prepare for segue DetailsViewController")
} else {
print("prepare for segue other")
}
}
I have a registration view controller. In it I process the input provided by the user soon as he clicks on the register button. This button in the view is connected to an IBAction where I validate the input provided.
How is t possible to trigger the segue and pass the data within the IBAction (not override prepareforsegue) to the next view controller? If the validation fails it shouldn't attempt to execute segue but rather stay on same view to display validation errors.
Thanks for support. The question has been asked in different ways before surely but I wasn't able to find a good combine of segue in ibaction and passing data too.
You can create a segue from one view controller to another and can put a check in your button's IBAction, like this:
if (validationPasses)
{
self.performSegueWithIdentifier("segueIdentifier", sender: self)
}
And if you don't won't to override your prepareforsegue, you can pass the data using delegates.
However, by overriding prepareforsegue, you can pass data to your next view controller like this:
override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
if (segue.identifier == "segueIdentifier") {
// pass data to next view controller
let vc : NextViewController = segue!.destinationViewController as NextViewController
vc.someVariable = someValue
}
}
Here NextViewController is your next viewcontroller, change its name to your next view controller and in this view controller define variable to whom you want to pass value, in this case it is someVariable
I have a segue running form a Collection View (wrapped in a view controller) in to a another view controller, how ever the function never gets called:
func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
println(segue.identifier)
println(sender)
println("SEGUE SELECTED: \(segue.identifier)")
if(segue.identifier == "segueToDetailView") {
let cell = sender as CollectionViewCell;
}
}
Have placed a breakpoint at start of function but never reached.
Any input appreciated.
I will suggest not to create segue(s) from cell or any object(like button).
Create segue from one ViewController to OtherViewController with unique identifier.
And then call the performSegueWithIdentifier yourself using the identifier.