How to perform conditional segue - swift

I've created a segue through IB. When buttonA is clicked, a transition to viewB will occur.
In the button click action, I have performSegue(withIdentifier:sender:) wrapped in a condition. I want the segue to occur only if the condition is true.
However, once the user clicks the button, the segue happens before the condition is even run. What is the best way to transition programmatically while still using segue identifiers defined in IB?

You have created segue from the UIButton to a viewController that is the reason segue happens before the execution of condition. Instead of that remove that segue from storyboard and create another from your ViewController to DestinationViewController.

Related

How to segue across iOS Navigation Controller programmatically using Swift?

My question is very much like these two:
IOS - How to segue programmatically using swift
How do I create a segue that can be called from a button that is created programmatically?
EXCEPT that my segue is to a Navigation Controller, like this: Main->NC->VC2>VC3.
The segue from Main to VC2 works fine when I trigger it with a button in my first view controller. It does not work when the segue is called by code. I need to have the segue triggered automatically in response to certain conditions determined by the code in Main.
When the button is linked to a function coded in Main, it still works. Code in the button function definition runs and the segue occurs. When I try to trigger the segue in the code for the function, using
performSegueWithIdentifier("showHelp", sender: nil)
or
performSegueWithIdentifier("showHelp", sender: self)
I get an error:
Warning: Attempt to present <UINavigationController: 0x7fc8e1043000> on <myApp.Main: 0x7fc8e0d17b10> whose view is not in the window hierarchy!
The button continues to trigger the segue, despite the warning, but not when the button's function is called by other code.
self.navigationController?.pushViewController(nextViewController, animated: true)

Why is a storyboard popover segue appearing on a subsequent view within a navigation controller

this is odd, but I'll try to explain the best I can.
I have a navigation controller which has a view. The view asks a simple question. That view then has two segues available -- one on the view for a correct answer, which is a "show" on the navigation controller and the other for an incorrect answer which is a "popover".
The segues are tied to the view and the answer box for the show and popover respectively.
I'm testing the answer on button press and using performSegueWithIdentifier to then show the appropriate window.
if (answerField.text == "2") {
println("Correct")
performSegueWithIdentifier("Correct", sender: sender)
} else {
println("Incorrect")
performSegueWithIdentifier("Error", sender: sender)
}
The problem I'm having is that if I get the answer correct, it moves fine to the next view, but it shows the "incorrect" popover view after segueing to the correct one.
I know that sounds complicated, but it's a super simple app at present. I suspect I'm just doing it wrong. Of note is that I also get an error "Presenting view controllers on detached view controllers is discouraged" which may be related.
Many thanks for any assistance anyone can provide.
D.
It sounds like you have one or both of the segues hooked up directly to the button in your storyboard, which will trigger the segue automatically on the button press even when you don't call performSegueWithIdentifier(_:) in code. You are then setting up an IBAction method which is also called on the button press, where you are then programmatically performing the segue again.
You can check this by going to your storyboard and selecting the button. Go to the connections inspector on the right, and I expect you'll see a Triggered Segues section, with an "action" triggering your "show" segue. You can remove this by clicking the cross next to the connection.
For segues that should be initiated programmatically, you should create a segue by dragging from the view controller object (rather from a control / actionable element) to the next view controller. This will create a generic segue that is only triggered by performSegueWithIdentifier(_:) in code.
As you have noticed, since your segue is for a popover presentation it will complain unless it is explicitly anchored to a particular view in your storyboard. You can still drag the segue from the view controller object to the popover view controller, but you must manually hook up the anchor: select the segue in the storyboard, choose the attributes inspector on the right, and drag from the circle in the "Anchor" field to the text field you want to anchor to.

Changing the behavior of UIBarButtonItem i.e shifting from action to segue and vice-a-versa

I have a UIBarButtonItems, left side is edit and right side is add/done;
Now When edit is not clicked the action for right side button is to take me to next view controller and I have setup this using segue in storyboard.
However when edit is clicked I want to perform a different action i.e I don't want to go to that new view controller rather disable editing when clicked on that right side UIBarButtonItem.
Now I also have a IBAction done; which disables the editing.
But how to shift the behavior between add/done;
I can do this via programming; But since I have added the segue via storyboard, I wanted to know if there is a way I can switch between segue from storyboard and the IBAction in my controller.
Thanks.
Your problem is that you connect button action to perform specific segue.
You can
create segue between your controllers by Ctrl+dragging from one VC to another (not from specific view to view controller). You can do it easily in VC list window (to the left of your Storyboard scene). Don't forget give IDs to your segues.
connect your button actions to VC action listeners
in these listeners use your logic and invoke with specific identifier
- (void)performSegueWithIdentifier:(NSString *)identifier sender:(id)sender
That's all!

Possible to have all cells segue to same view controller?

Instead of control-dragging every cell to the other view controller, is there a way to make them all segue to the view controller more easily? I would also need to add a Segue Identifier to the individual segues as well.
That is exactly why you have a tableview delegate method.
– tableView:didDeselectRowAtIndexPath:
whatever cell in the table this method will get invoked and there you can call for whichever transition like push,model etc programmatically in code.
This sounds like something you should do programmatically rather than in interface builder. You'll want to set the selection action for the cells to trigger the Segue.
You can create a manual segue from one view controller to another. Just select view controller from the bottom bar (where you see first responder and all) and ctrl drag to other view controller. Select the segue and give it a unique identifier (TransitionSegue in this example) from attributes inspector. From code call the segue whenever you want a transition.
[self performSegueWithIdentifier: #"TransitionSegue" sender: self];
Hope this helps.

Segue not performing

I'm currently facing something I find rather strange.
In my storyboard, there is a TableViewController filled with static cells.
I would like to perform a simple segue (a push to another view controller) when I select one of the rows.
So I "ControlDrag" from the concerned table cell to the sibling controller, but when tap one the cell, nothing happens. Next to that, I did try assigning the segue triggering to the accessory view of the cell (a disclosure button). And in that case, the segue is effectively triggered.
So here is my question : Should I use the "programmatic way" to handle the tap on the cell (tableview delegate methods and manual segue performing), or is there something I'm missing in the interface builder? And btw how could we explain the behavior difference with the accessory button view ?
Here is two screenshot
Cell selection that should trigger segue
And, the accessory action which performs the segue
I finally found what the problem was. I had a gesture recognizer attached to the view controller, and it was catching the tap event on the cell.