Multiple segues to one UIViewController - ios

In my storyboard I have a TextInputViewController (subclass of UIViewController). I have multiples push segues leading to TextInputViewController with different identifiers from various view controllers. However every time one of these segues are called they seem to go to the same instance of TextInputViewController which causes a very strange behaviour.
Is there a way to make each segue create a different instance of TextInputViewController?

Segues always create a new instance of the destinationViewController (with the exception of the unwind segue which simply returns to a previously created viewController).
The behavior you are seeing must be caused by some other state external to the viewController since it is a new instance.
You can read more about using Segues here.

Related

How to safely try to perform segue in Swift while ignoring/handling manually possible exceptions?

I'm trying to make a custom view controller for use in my projects, that has possible 3 segues from it. But those are not mandatory.
When view controller loads i'm calling a method "trySegues()" that should try to perform all 3 of those segues. Segues are custom, so each successful call will be handled and registered in my code.
In Objective-C i would do that using "#try - #catch" so all the successful calls will go forward, while if one of those segues is not set, it'll raise an exception, but it will be handled by me manually so it won't break the execution of the program.
Is there a way to do the same in Swift?
Using Optionals to simulate an exception won't work, since the performSegueWithIdentifier function returns no value.
In no imaginable way is #try-#catch-ing a performSegueWithIdentifier: the appropriate approach to this challenge. Not in Objective-C. Not in Swift.
Segues can't (or shouldn't) exist independently of storyboards. After all, if you were try to instantiate a segue, the class name is UIStoryboardSegue. The fact that this class even exists publicly is not so that you can instantiate it and add it at run time. It exists so that you can subclass the segue, choose your subclass on the storyboard, and set up a segue with custom behavior:
In Objective-C and Swift, exceptions are reserved for truly exceptional behavior. Behavior which can be prevented at development time. We should not be relying on #try-#catch blocks during run-time by the time we've released our app. We should have fixed our app so that there's nothing to #catch.
So with this said, the only way that performSegueWithIdentifier: can throw an exception is if the segue identifier we gave it does not exist. The only reason the segue shouldn't exist is because we made a typo somewhere.
The segues are hooked up and defined at compile time. There is no public mechanism for checking whether or not a particular segue exists because we just shouldn't be doing this at all.
Now, with all that said, if we want to dynamically push or modally present a particular view controller at run time, and we can't know at compile time what view controller it will be (or from what view controller we're getting to it from), then we shouldn't be presenting it via a segue.
Instead, we should be using one of the presentation options the UIViewController class defines.
Your options are:
presentViewController(_:animated:completion:)
showViewController(_:sender:)
showDetailViewController(_:sender:)
And in place of an unwind segue, you'd want something like this:
dismissViewControllerAnimated(_:completion:)

Accessing linked Segues created in a Storyboard

I am trying to create a class that is similar in functionality to the UITabBarController, but with some fundamentally different functionality. It is called a dropdownViewController and has a primary content view with a UITabBar-like interface at the top of the screen that allows for other UIViewControllers to be modally presented and dismissed over this primary viewController.
I would like this class to be able to be set up using the storyboard to some extent, and I have created a custom Segue that connects my dropDownViewController class with each of its child viewControllers.
My current solution is to assign identifiers to each of the Segues that are then stored in array within the dropdownViewController. I can call the segues programmatically using the performSegueWithIdentifer: method, but this solution isn't as flexible or intuitive as I would like to to be.
Right now, all the custom Segues that I have setup are connected to the "manual" triggered segue in the storyboard connections panel for the dropdownViewController. (I would put screenshots but this is my first post)
However, I want to mimic the functionality of the UITabBarController class, which has an alternate triggered segue in the storyboard connections panel called viewControllers that each of its child views are assigned to. Unless there are some compile-time macros handling these story board interactions, I assume that the UITabBarController uses these connections to determine what it's view controllers are. However, I can't figure out how to setup this functionality with my own class
After searching around for a solution, it seems likely that this is functionality Apple kept for its own use and is limited to their own classes as a feature in Xcode, but if anyone has solutions or ideas it would be greatly appreciated.
I haven't tried this, but I think you should be able to do it with your own custom segues. In the perform method, you would just add the destination view controller to the source view controller's (DropDownViewController) array of view controllers. In the DropDownViewController's viewDidLoad method (or maybe in an initializer or awakeFromNib, not sure which is most appropriate), you would execute all these segues so that they run right after the controller is loaded like is done for a tab bar controller.

Segue to a subclass of some view controller

I'm using a storyboard. Let's say I have a view controller that's named MYviewController.
In - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender; I would like to substitute the view controller that I'm segueing to, by one of its child, for example: MYviewControllerChild1 OR MYviewControllerChild2. The child that's segued to depends on the sender parameter.
These view controllers have the same scene (in the storyboard). Only their behaviour is slightly different.
I have a tableView that shows the user the settings of the application. When he clicks a cell, it segues to a viewController where he can modify the value of some setting. Some of theses are alphanumeric, others are numeric. Depending on which cell is clicked, I'd like the input viewController to format the value accordingly (if it's a decimal value I'll use a NSNumberFormatter for example).
Is that possible?
As mentioned in comments to your OP, I believe you should handle this kind of scenario in one viewcontroller.
However, if you insist on using separate controllers, maybe because you think the functionality will be expanded later down the line and therefore add more diversity, you need to handle this by creating multiple storyboard scenes - one for each child controller.
The destination view controller in prepareForSegue is imposed by the viewcontroller at the end of the segue in the storyboard. I don't think there is any way to override that.
As described, your problem isn't really a good candidate for a storyboard. If you use a storyboard you will have to create and sync multiple scenes. Several possible solutions::
Create multiple storyboard scenes and invoke them manually via performSegueWithIdentifier.
Use a nib file instead of a storyboard for this scene. You can use a single nib file since the view controller is created outside the storyboard with [[VCClass alloc] initWithNibFile: bundle: You can create the appropriate view controller class and pass the same nib file to all instances.
Use a single storyboard scene and view controller and pass in typing information in your prepareForSegue.

View Controller Cannot Find Segue With Identifier

I have 3 view controllers in a part of my storyboard. I also have 2 push segues, one switches the first view controller to the second one, and the other one switches the second view controller to the third one.
I perform both segues programmatically, and I have set all three view controllers to use the same custom class ( Called RegViewController ).
Everything works fine with the first segue, but the second one throws an exception saying
Crash: Receiver (<RegViewController: 0xab74b50>) has no segue with identifier 'a'
I set the identifier for second segue to "a" to make sure it is short and I'm not making any mistake.
Anyways, I'm sure that my view controller has a push segue with that identifier and I dunno if I'm making any mistake logically !
Any ideas ?
Found the problem :
Assigning 3 view controllers to same custom class, results in errors when you're trying to perform a segue, because the segue with desired identifier is not created from every view controller using that custom class. Using different custom classes would solve the problem.
check your segue identifier. because your segue identifier doesn't same in your code or you are declared identifier name different on your storyboard

Using Storyboards Segues

I have a question about how I use segues with Storyboard in Xcode.
I have an application with 3 views, and I would load them with animation modal "Cross Dissolve".
Every time I load a new view without dismiss the current one, it still occupying memory?
I'm realizing that after changing multiple views my APP becomes slow.
If yes, how is the right way to change views in sequence?
When you go back from 3 to 1 you should use an unwind segue. That will cause 3 and 2 to be deallocated (if you're not keeping a strong pointer to them), and you will actually go back to the same instance of 1 (rather than creating a new one). In general, you should not go backwards using a segue other than an unwind segue.
Rather than specifying the "back to 1" segue in the storyboard, you may want to instantiate it in code using the method -initWithIdentifier:source:destination:. That'll permit you to specify the destination as your first view controller instead of creating a new view controller to transition to.
In fact, you should probably specify all the segues between these view controllers programmatically if you don't want to instantiate new copies with each switch.

Resources