performSegue(withSender: sender:) does not work - no errors displayed - swift

func checkForRecipes(noRecords: Bool) {
//segue to addNewRecipe page
if noRecords == true{
print("Can't Find any Recipes!")
self.performSegue(withIdentifier: "ToAddNewRecipeVC", sender: self)
}else{
print("error, noRecords not equal to zero")
}
I am able to segue successfully via the storyboard but want to do so programmatically based on information returned from a delegate.
Upon running the app, the information from the delegate is successfully sent to the function "checkForRecipes" -i.e "noRecords" returns TRUE, but for some reason, the below line of code within that function does not seem to execute (and no errors are thrown):
self.performSegue(withIdentifier: "ToAddNewRecipeVC", sender: self)
The app starts up but stops at the main screen, whereas it should segue to the "AddNewRecipe" view controller.
The segue itself definitely has a segue ID of "ToAddNewRecipeVC". I have also tried dispatching to the main queue (to no avail) based on the following thread.
I'm stumped - what's going wrong here?

OK, it looks as though I have solved the problem. I embedded the main view controller into a navigation controller and now everything works as intended. I tried this same tactic earlier and it kept throwing up errors. grrr!
Anyway - thank you to all for the input!

Related

How to get rid of or change a storyboard created segue programatically

I have a segue from one view controller to another, which was created in the storyboard of my project. I'm wondering if there is a way to change or get rid of that segue through code. Thanks, using Xcode 9 Swift 4.
Apparently it's not possible... look at the answer on this post. And the documentation says this about creating segues:
"You do not create segue objects directly. Instead, the storyboard runtime creates them when it must perform a segue between two view controllers."
Although it's not about changing or deleting the segue, I think it's the same logic.
If you just want to avoid the segue to happen you can do that inside "shouldPerformSegue" (like vacawama said in the comments):
override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool {
if identifier == "aSegueIWantToDisable" {
return false
}
return true
}

Swift - TabBarController - Decide segue at runtime

i have the following situation:
In my TabBarController i have multiple tabs and it all works fine, but:
The destination of one specific tab is dynamic.
If a certain condition matches, this specific tab should open a NavigationViewController.
If an other condition matches, this specific tab should open a ViewController.
Are there any built in solutions?
How can i modify the destination of a tab at runtime?
Greetings and thanks
Long long ago, in a galaxy far far away...
Segues didn't even exist. So yeah
The UITabBarController has a setter in which you can pass the new view controllers you want it to handle. You won't be able to decide what shows at the point of the tapping this way, but you'll be able to change the controllers as the condition changes.
open func setViewControllers(_ viewControllers: [UIViewController]?, animated: Bool)
If you however DO need to decide as the tab is tapped... You could have your tab controller direct to a controller that's essentially empty, and use view controller containment for that controller to have the 2 options on it, and have one of them hidden. Pretty doable from the storyboard with very little supporting code. I think I prefer this option.
If you would rather continue to use Segues, then you can perform a specific Segue depending on the state of some condition variable like this:
func presentAppropriateView() {
if condition {
performSegue(withIdentifier: "ToNavBar", sender: self)
} else {
performSegue(withIdentifier: "ToVC", sender: self)
}
}
write a delegate method which you want to perform on certain condition on runtime and call
[self.tabBarController setSelectedIndex:0];
where index could be of your choice

Change key to true then show view in swift

OK, so I've added a view onto my Application that asks the user to accept or decline the Terms of Service. I have it so when they click accept, it changes the key "TermsAccepted" to true. If they close the app, and re-open it, it gives them access. However I'd like to be able to give them access without re-opening the app first.
So in my ViewController (Main Screen), in my viewDidLoad I have the following:
if NSUserDefaults.standardUserDefaults().boolForKey("TermsAccepted") {
// They've been accepted, do nothing.
} else {
let termsView = self.storyboard?.instantiateViewControllerWithIdentifier("FirstLaunchTerms") as! FirstLaunchTermsView
self.presentViewController(termsView, animated: true, completion: null
}
In the 'LaunchTermsView' I have the following code for when they accept the terms.
#IBAction func acceptTerms(sender : AnyObject)
{
NSUserDefaults.standardUserDefaults().setBool(true, forKey: "TermsAccepted")
}
And thi works fine, but they have to re-open the application.
I tried to just have it so the button opens the Main View at the same time as those terms are accepted (After the key is updated) but it gives me the following error.
fatal error: unexpectedly found nil while unwrapping an Optional value (lldb)
I assumed this meant that it was wanting to re-open the launch terms view again, so I tried to move all the code from viewDidLoad to viewWillAppear so it checks each time, but it just gives the same error. (it was a long shot try before I posted on here).
I had a look at some posts on here, but a lot of them were in ObjC or just didn't give me a solution or any form of help to trying to find one myself.
As you're presenting your terms view controller you should simply be able to dismiss it when you're done with it. You don't show any other code so I'm assuming that your 'home' view controller is waiting to be revealed underneath (you don't need to try to show it again).

performSegueWithIdentifier not working properly with swift

I am currently trying to segue to a different view controller when a button is pressed. The button's action method is called correctly, but when it calls the perform segue with identifier it crashes the app and says "terminating with uncaught exception of type NSException". I have the segue identifier as "switchToMap". I segue to the same page from a different place in the app as well, but that seems to work just fine. Does anyone have any ideas?
func mapButtonPressed (sender: UIButton) {
performSegueWithIdentifier("switchToMap", sender: sender)
}
The other place the map page is segued to looks like this. It is part of a switch statement.
case 2:
performSegueWithIdentifier("map", sender: indexPath.item)

Segue following a change in criteria from a local notification in Swift

I have created a local notification in Swift which gives the option to end a current game without having to go back in to the app. That's all fine and works as it should. The issue I'm having is that if the user does this, I don't want them to go back to the Game view controller if that happens to be the last view that was open when the app entered the background. I would like them to go back to the app's Home view controller instead.
I expected to be able to add a perform segue to my Game view controller in the following way, should the criteria match. I tried adding it to viewDidAppear(), but it didn't work:
override func viewDidAppear(animated: Bool) {
if isThereACurrentGame() == false {
performSegueWithIdentifier("unwindToHomeScreen", sender: self)
}
}
Is this something to do with viewDidAppear() not being called when the app comes back to the foreground? If so, what might an alternative be?
P.S. My isThereACurrentGame() function works as it should, as does the performSegueWithIdentifier elsewhere in the view controller, so these aren't the cause of the problem.