Move Between different Navigation Controllers in Xcode Swift - swift

I want to move from one UINavigatioController to other UINavigatioController. Scenario is First I am at ContactVC and after pressing any cell I will be move to ChatVC. Now when I press the back button on chatVC I want to move back on InboxVC. How can I achieve this scenario.

A UINavigationController is a stack based navigation system. This means when you navigate forwards you simply add another UIViewController to the stack, and when you navigate backwards you pop a UIViewContrller off the stack.
To do what you are proposing you will need to change the underlying UIViewController's that are currently in the navigation stack. You can do this by using func setViewControllers(_ viewControllers: [UIViewController], animated: Bool) on UINavigationController programatically, but you can't do it through a storyboard as thats not how a UINavigationController is intended to be used.

UINavigationController controller keeps a stack of the views (in simple words to understand) when a push a new view controller onto it. So when you press back it essentially pops the last view controller to display its parent controller. This is also normal user behaviour on the iOS platform.
The behaviour you are looking in counter-intuitive to the user since you are breaking their flow of navigation. But if you can a have a strong case for it. You can manually create a back button which can push to the inbox controller to get this sort of behaviour in code or in interface builder.
Another way to achieve this perhaps what you can see in other apps is:
you have a Signup view controller (which might be the form). When the signup is completed.
change the root view controller of the window to Inbox controller and
The same time, push the Chat controller so when your user pushes the back button, they will be taken back to the Inbox.

Related

Present ViewController from its title

Background
I am developing an application which contains a top nav bar with an icon that allows to go back to the main ViewController.
As there as several ViewControllers, I don't want to duplicate the segue on each ViewController. I would prefer to create a custom class for the top nav bar and be able to programmatically present the main ViewController. I found that I could maybe call present(viewControllerToPresent:animated:completion)
Questions
Is this the right way to do it?
How do I access the controller I need to pass to this function?
Is there a method which allows to get the controller from its title?
Also, as the main ViewController has already been instantiated when the application started, do I need to instantiate a new one or can I get a reference to the existing one?
So if I get this correct you click mainVC->firstVC->secondVC->nthVC and then you'd want to go directly back to mainVC ? View controllers are stacked so what I'd do is just dismiss all those view controllers that are above mainVC.

view controllers using storyboard

i am trying to switch between two view controllers using storyboard. I create a modal seague by control-dragging (on buttons) from 1st view controller to 2nd, and then from the 2nd to the first.
So whenever I click on a button in 1st VC, it takes me to the 2nd VC. This time when i click the button on second VC, does it take me back to the original instance of the 1st VC or it creates a new instance?
If it takes me to the same instance, and user had written some data in some textfields, is there anyway to retain that on screen? (I might want to save them in some variables, and since the program will return back to the same instancem i'll be able to get the variables back)
If it doesn't take me to the same instance, is there any method to do so?
I tried making an instance of 2nd VC and using self.navigarionController push...(instance) but this doesn't swtich the controller.
If i do this pushing using the storyboard, and i do pop in my 2nd VC, it doesn't get popped either.
(and i would also couldn't understand the difference between push,modal and custom seagues)
Create the modal segue from VC1's button to VC2, but not the reverse one. When the VC2's button is tapped, call dismissViewControllerAnimated:completion: to return to where you were.
If you used a push segue instead, you would call popViewControllerAnimated: to go back but that only works if you have your view controllers managed by a UINavigationController.
You can think of push as a way of stepping through a sequence of related scenes while modal is something that's a bit out of the normal flow of the application. (That's not a firm rule but it's a starting point for deciding which way to go.) For 'custom', you write the segue code, so you decide what happens.

Can someone explain UINavigationController setViewController and popToViewController

I'm familiar with the idea of creating a new viewcontroller and pushing it onto the stack. So far I have just created an instance of my view controller and pushed it. Now I am running into a problem that my 3 different view controllers are related ways of looking at the data. My RootViewController has 3 icons to start, and when you press on an icon, you push the first view controller. I currently do not set the view controllers in an array since I'm not sure what that buys me or how that works.
Scenario 1: Click on icon 1 (push vc1), click on a table in a popover in vc1, it'll push to vc3. Then you click on something in vc3, and it'll go to vc1.
Scenario 2: Click on icon 3 (push vc3), click on something and go to vc1.
So the problem I'm having is in scenario 1, it would seem to make the most sense to pop back to vc1 so they don't have a stack of vc1/vc3/vc1 and are looking at the data twice like that. But in scenario 2, since I started at vc3 instd of vc1, I should push vc1. But in both scenarios, the user is clicking on the same thing to go to vc1 from vc3, so how do I tell which viewController they came from in order to push or pop to vc1?
So I guess that's where I thought setViewControllers or popToViewController might come in handy, but I'm not sure how those work and if there's some simple example snippet someone can provide to get me started (assuming this approach is ok). Thanks!
It sounds to me, from your description, that you should be using a navigation controller that you push and pop onto and off. Btw, the navigation bar doesn't have to be visible.
It also sounds like you should sometimes pop the current vc before pushing the next vc. You will need to check the count of the viewControllers array - if the current count is greater than one then pop before pushing, otherwise just push as you are at the root view controller.
Or, you could use popToRootViewControllerAnimated:NO each time before pushing.
UINavigationController is what allows you to manage your views.
setViewController allows you to set which controller handles your view.
popToViewController takes the current view controller off the stack to the specified view.
IMO... The last 2 promote spaghetti logic and should be used sparingly.

What to do about "Finishing up a navigation transition in an unexpected state. Navigation Bar subview tree might get corrupted."

I'm writing an iPhone app using Appcelerator Titanium Mobile. I am hiding and showing the tab group based on what window has focus.
dashWin.addEventListener("focus",function(e) {
if (dashWin.tabGroupVisible == true) {
dashWin.tabGroupVisible=false;
tabGroup.animate({bottom:-50,duration:500});
}
});
The code above hides the tab group when dashWin receives a focus event. However, I see this message in the Titanium console when the event fires while running in the iPhone simulator:
Finishing up a navigation transition in an unexpected state. Navigation Bar subview tree might get corrupted.
A Google search turns up one result: Another StackOverflow question that may have a hint as to what's going on.
I got this error when I linked Action Segue or Selection Segue from one view to another view through storyboard and performed the same segue programmatically again, which makes the navigation controller perform the same segue twice.
2 solutions for this case:
Removing the code that pushes the view. Just let storyboard perform the segue for you. This is good for most situations.
Replacing Action Segue or Selection Segue with Manual Section and do - (void)performSegueWithIdentifier:(NSString *)identifier sender:(id)sender by yourself. You may find this solution useful when you want to customize the behavior of segue according to the sender.
Usually a tab group acts as the root of your app's navigation. When a user taps a tab, that tab's window is focused.
Next, when a user triggers an action that requires a new window appear, it usually appears either modally or on top (in the navigation stack sense) of the current window. In the latter case, tell the current tab to open the new window.
If you set the tabBarHidden property to false (when you create the new window), the tab bar will be hidden for you when the new window is opened by the current tab.
Will this more standard approach work for you?
I had segues that were leading back to my main navigation controller which was causing this. I fixed the problem by setting the main navigation controller back to the top of the stack. Here is the code:
- (void) viewDidAppear:(BOOL)animated
{
[self.navigationController popToRootViewControllerAnimated:NO];
}
Recently, I've faced the same problem. The reason was:
-I was trying to pop view controller twice by mistake.
you can check this crash by setting breakpoints on push and pop View controllers

Switching multiple views using a delegate

I'm developing an iPhone app that, amongst other things, allows the user to sign up, log in and logout of a remote web server.
For this piece of app functionality I have 3 view controllers defined.
SignupViewController
LoginViewController
LogoutViewController
and each has a respective xib file.
I want to be able to switch between views based on what button is pressed. For example:
The SignupView will have a signup button and a login button, if the signup button is pressed I want to switch views to the LogoutView and if the login button is pressed then I want to switch views to the LoginView.
Similarly the LoginView will have a login button and when pressed will switch views to the LogoutView
And finallty the LogoutView will have a logout button who's action will switch views to the LoginView
I've been thinking of a number of different strategies to take when developing this but I'm not sure which one is the best.
One idea, and probably the easiest to implement is to have a single view controller with three different views defined in the xib file and to let the controller handle the switching.
I have some issues with this approach, the xib file will be quite large and might be slow to load while my controller logic will likely become very complex.
The second idea and my current approach is to have a parent view controller which is responsible for switching in and out one of the three sub views.
The problem I'm having with this is that button actions can only be assigned to methods in the current sub view controller. In my case the method I need to call to handle the switch is in the parent controller and this method is not available to my sub views.
A delegate would seem the perfect answer here as I could to ask the parent controller to execute the switch method but I'm still unsure as to how I would define a delegate to perform this operation in my code.
Can anyone help with this? Is there a third strategy that would work better than the delegate strategy?
If you use a UINavigationController as your root, then you can pop and push whatever controllers you want. So, you might start something like this:
[rootController.navigationController pushViewController: someVC animated: YES];
Then, later, when you want to switch from someVC to someOtherVC, you'd do this:
UINavigationController *navCon = self.navigationController;
[navCon popViewControllerAnimated: NO]; // get rid of me
[navCon pushViewController: someOtherController animated: YES]; // add new controller.
NOTE: All code typed in browser and untested, but I think you should get the idea from this.
You could use delegates or notifications or other things, but the push/pop thing on the nav controller is really handy for this sort of view-stack rearranging. NOTE: If you don't like the nav controller look, you can hide the nav-bar! :)