Segue to a viewcontroller in another storyboard without a navigationcontroller - ios

I want to move to another viewcontroller in another storyboard and the view controller im in is not embedded in a navigationctroller.
Normally i would just instantiate the viewcontroller and push it to the navigationcontroller stack but since this is not possible i dont know what to do, and I cant seem to find any help on this.
Any suggestions?

It depends on what you're trying to achieve in the app, but a few options are: present it as a modal controller, create your own custom type of segue, replace the root controller in the app's window....

Related

One segue to rule them all

I have 4 ViewControllers in my storyboard. I want all of them to be able to access my "Settings" ViewController by performSegue.
Is it possible to have ONE segue to perform this, instead of ctrl + drag from each and every ViewController to my "Settings" ViewController?
No its not possible with a single segue. You need 4 different segues from 4 different ViewControllers. But you can do this programatically.
Make an extension for UIVIewController
extension UIViewController
{
func showSettingsScreen()
{
let storyBoard = UIStoryboard(name: "YourStoryBoardName", bundle:nil)
let settingsScreen = storyBoard.instantiateViewControllerWithIdentifier("YourSettingsViewControllerID")
self.navigationController?.pushViewController(settingsScreen, animated: true)
}
}
Now you can call showSettingsScreen() from any of your view controllers(Make sure this view controller has a navigation controller).
You cannot do that. A segue has only one source and one destination. You could programatically instantiate your Settings ViewController and display it either by using push or by using present. What you should think of though is why do you have to go to settings from so many places. It might be a sign of bad design and duplicate code. Usually applications have only one such button/action that can be accessed from multiple screens (by using some kind of container view implementation) or from only one screen.
I really dont think so there is a way to do so. U ought to connect ur SettingsViewController to all of your 4 View Controllers, add segue , and define a segue identifier which is used in
prepareForSegue:sender:
or
shouldPerformSegueWithIdentifier:sender:
methods. U can access segues through these identifiers. If u find "ctrl + drag from each and every ViewController to "Settings" ViewController " tasky you can opt for Navigation Controller as well. U just have to embed Navigation Controller in your storyboard and define Storyboard Id for every View Controller and you are done. Just use storyboard id of view controller to be instantiated and u good to go.
ViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:#"ViewController"];
[self.navigationController pushViewController:vc animated:YES];
Apart for assigning storyboard id you dont have to worry about storyboard ,No ctrl+drag thing.
I thought of one more elegant solution i.e. using Container View. You can take button to switch, SettingsViewController as common, in your Container View Controller while displaying every ViewController.
happy Coding..
There is one way to do this. Create a root view controller and matching view which contains a single embedded view. Add your segue to this root controller. Then in your app you switch in the other view controllers using standard child container techniques. This is pretty much the concept that UINavigationControllers use.
One advantage from this is that if you want to have common elements which are visible to all controllers then you can add them to your root controller.
But it all depends on what you are trying to achieve.

poptorootviewcontroller and instruct rootviewcontroller to perform some action

I have a navigationcontroller, and under that I have controller A as rootviewcontroller and controller B is linked to A through a default push segue.
What I want to do is to when some action is pressed in B, I will ask the navigation controller to pop to rootviewcontroller, which is A, and apply some popovercontroller(or just another view or another window) on top of A.
Someone suggested me to ask appdelegate to create another window on top of current uiwindow. I think it is possible and I want to know if there is any simpler/more elegant solution for this problem.
a general solution of what I can do will be appreciated and some simple code samples in Swift will be much more appreciated :P
I will just provide my own answer here.
According to my own experience, there is no popping segue and therefore we cannot exactly get destination view controller from segue. however, UINavigationController has an attribute viewControllers which basically are all children controllers on the stack.
so before popToRootViewController, just get the VC but calling self.nagivationController.viewControllers[0] and you get the root view controller already

Call storyboard scene without creating a segue in swift?

I created a scene and tried to link the class to the scene and create a segue with the storyboard and use self.performSegueWithIdentifier("SegueID", sender: self) and no matter what I did (i.e. clean build) I still got the same error "reason: 'Receiver () has no segue with identifier 'SegueID''"
I think the best way to solve this is to avoid the segue in this instance all together.
So is there a way to make a call from a view in the code to transition to another view without using segue in swift?
Edit
I've tried all three ways but to no avail. The most common way of just creating a segue between two scenes in storyboard and giving it a name, in my case "Details", but the segue isn't recognized.
So I tried the next way of loading it from a nib and then pushing that nib onto the navigation stack, but when compile and build the program and I click on the button to present to new view controller, nothing happens except for the function println executing.
And trying to use the destination controller manually just didn't work. instantiateViewControllerWithIdentifier expects a string and complains that there are too many arguments in the call
Your code doesn't work because you need to setup a segue in storyboards with a specific ID that you pass as an argument when you call performSegueWithIdentifier. So, in your case, you need to create a segue with ID "SegueID", since that is the string that you are passing to that call.
If you don't want to do this using storyboards, you can still just use UINavigationController directly (after all, a segue uses a UINavigationController under the hood).
Then you just need to instantiate your destination view controller manually (e.g. by using
self.storyboard.instantiateViewControllerWithIdentifier(<your vc id from the storyboard>, animated:true)
or by loading it from a nib
init(nibName:bundle:)
and then push it onto the navigation stack using
self.navigationController.pushViewController(<the formerly instantiaded vc>)

Loop loading UIViewControllers in storyboards

I'm using storyboard and i want to know if there is a way to use a UINavigationController to navigate from A->B->A->B and so on. The UIViewControllers are the same but the info loaded in each one is different.
I tried using segues but the problem is that the info loaded into the classes is not saved. So when i do A->B->A and i go back to the root, the info of root is the info loaded in the 2ยบ A. Because i'm using storyboards i don't create instances of the UIViewControllers and i think that is the problem, i only use [segue destinationViewController] in prepareForSegue. I think that one solution would be stop using storyboards and use Xibs, because that way i would create an instance of each class every time they were loaded and that would solve my problem.
I just wanted to know if there is a way to do this using storyboard, because changing to Xibs, would need a lot of work. Any suggestions?
I've never tried to do A -> B -> A -> B before. But I have tried to do A -> A -> A, and that doesn't work. A limitation of Storyboards is that you can't segue to another instance of the same VC.
However what you can do is pretty easy - instead of writing up the button to triggering a segue in the storyboard, wire it up to a method and push the new view controller onto the navigation stack manually.
- (IBAction)buttonTapped:(id)sender {
UIViewController *viewControllerA = [self.storyboard instantiateViewControllerWithIdentifier:#"viewControllerAIdentifier"];
[self.navigationController pushViewController:viewControllerA];
}
Note that "prepareForSegue" won't get called here so you'll have to configure the new VC instance as needed.

Add parameters to TabBar Storyboard segue

I have a TabBar with 3 buttons, the 2nd and 3nd buttons have a segue to the same controller, which should show different info depending on one param.
I've overridden TabBar class to implement.-
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender;
to be able to add my param just before performing the segue, but I must be missing something obvious because prepareForSegue is not getting called.
Is there anyway to achieve this without programmatically creating custom segues?
According to me you cannot interact with segue linked as "root" controllers.
Those segue are not "getting called" as they don't represent a transition between two view controllers.
If you look at Interface Builder there is no settings available for that kind of segue.
I had a similar issue in one of my project and solve the issue by setting the controllers programmatically. After that you add your view controller in storyboard and set a "Storyboard ID" in the right hand panel.
Then, you can instantiate your view controller by doing
[self.storyboard instantiateViewControllerWithIdentifier:#"YOUR_VIEW_CONTROLLER_ID"];
And affect them to your UITabBarController by doing
[self setViewControllers:viewControllers];
Hope this help!
Not sure if it's the best practice, but I finally ended up getting the selected tab from my controllers.-
self.tabBarController.selectedIndex
This simple way, I know what info should I show, without changing my storyboard segues.

Resources