Present ViewController from its title - swift

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.

Related

Objective - C How to manage multiple views with View Controller iphone

I am new in developing iOS apps. I am trying to develop a multiple views app. My doubt is how to manage a multiple views app with View Controller, I mean, I do not want to use Navigation Controller nor Tab Controller.
My idea is to show a first View to choose the language, and after this, I want to show some different profiles in a table view. When you choose the profile, you get into a menu where you have some different functionalities (Once in this menu, I might use Navigation Controller).
My problem is that I don't know how to manage these two first views. I don't know if I have to declare them in the appDelegate, or if I can do it nesting one to other, I mean, I do the first view, and when I pressed the button, I declare the new view. Once in the new view, when I pressed a row in the table view, I make the another view.
I know it is a little bit confusing, so I hope you could understand it quite well.
EDIT:
I want to clarify that I am not using storyboards. My main doubt is what to do with all de view controllers, Do I have to declare all of them in the appDelegate? or Can I declare each view in every controller?
If you are using storyboards, you can use Segue's to navigate between the views, so you would show your first view, then you could tie a button to the next view (by control dragging in storyboard). If you want to transition programmatically you can use the performSegueWithIdentifier method. You could use the same approach to get from your tableViewController to your next viewController by using the performSegueWithIdentifier method from within the tableViewController's didSelectRowAtIndexPath delegate method (i.e. when a user taps a cell).
That should get you started. Good luck!
EDIT:
You really should be using storyboards. It's the way to do things these days. If you refuse, then the best approach is to create a container view controller that manages your "children" view controllers. You can find information on doing this, as well as the methods needed to present/remove child view controllers here:
Custom Container View Controllers
You can use navigation controller with "hidden" property.
self.navController.navigationBarHidden = YES;
If you want to have two different views and transition between them, you will want to use UIViewControllers presented modally. Here is Apple's Guide to this.

UITabbar Controller

In my app i am using tabbar controller with 5 tabs,in 3 tabs,when click on a button it calls one View Controller. I am using same view controller for those 3 tabs so i am getting problem while calling same view in different tabs,So while changing the tab i dont want to call ViewWillAppear method. So what i have do? or else how to find previous selected index of the tabbar controller?
Thanks in Advance
I think you are not familiar with iOS Development.
In a TabbarController we can specify as much of UIViewcontroller/UINavigationController object.
if we need to re-use a UIViewcontroller you need to tag the view controller using a property object.
You need to use different instance of UIViewController for different tab.
While Showing a UIViewController its viewWillAppear got fired. we don't able to remove this behavior. But in most case we can handle such case with viewDidLoad (It is called once for an instance of view controller).
if we need to track the previously selected tab item we need to do our own work-around by using a shared class or static variable.
thanks,
Naveen Shan

using dismissModalViewControllerAnimated without deallocating modal view controller

I'm creating an app using the iPhone Utility App framework, and I'm trying to use a navigation controller on the flipside view, as there will be a lot of drilldown options on this view. When I'm done with this view, I call the following code:
- (IBAction)done:(id)sender
{
[self dismissModalViewControllerAnimated:YES];
}
When I dismiss this view, I want to be able to go back to the place in the navigation I was currently at when I reopen this view again. However, when I dismiss this view using this method, the vc gets deallocated, therefore the menu starts back at the beginning when I try to go back to the menu.
Thoughts?
You'll need to retain a reference to the object (I'm calling it the options controller). I would say the easiest way is to create an iVar in the presenting view controller that references the options controller. Then, when you go to present the options controller again, just present the referenced options controller rather than creating a new controller. If different view controller objects can present the options controller, you'll need to either pass that reference around, or store it in some object that all the other view controllers have access to.
Hmm not much code so maybe I'm misunderstanding your setup, but...
You could use the AppDelegate to store (as a property) your current position (index) in the views collection of the Navigation controller, and then write a method that pushes to that (stored) position when you re-visit it later.
Might be an easier way to do it though..
So what you want is to flip from a view to another view? If you want to keep the navigation bar status between flipping, I recommend you use only one view controller to control this 2 views. you can use + transitionFromView:toView:duration:options:completion: of UIView to flip views.

How does iOS know which view controller should be active?

If I want to replace one screen of an app with another, but I don't use a navbar/tabbar controller, then I could just remove oldViewController.view from window and add newViewController.view to it. That's all, now newViewController will get rotation events, etc.
But UIView does not reference "its" controller, so how is this possible, how iOS know it should make newViewController an active one? Does iOS do some magic, it internally references controller from view or what?
UPDATE:
I think I was misunderstood: I don't ask how to make some view controller an active one - I know that. I'm just curious, how is it possible that I pass some view to UIWindow object ([window addSubview:view]) and it somehow finds view controller although view doesn't know its controller.
yeh I had the same question like you. and I figured it out.
UIView is derived from UIResponder. and UIView must subclass UIResponder::nextResponder.
Its default implementation is returning a view controller of the view (if it hadn't, it would be super view)
So, consequently view can see its controller. that means window know the topmost view and also
its controller.
good luck.
Unfortunately, iOS only send events to the first ViewController of the stack. You can try and present a new one on the top of others with video for example, it will never rotate.
If you don't use navbar/tabbar controller you will have to add and remove everytime from the Window to keep only one at the time if you wand to have events.
The main UIWindow class for your application will have a view controller set in its rootViewController property. That controller's view is the "main" view for the app. This is usually setup in the main .xib for the project. That view controller will receive the usual events like "viewDidAppear" or "willRotateToInterfaceOrientation". You can put up your own view over top of it if you want to, but you will need to manage those events yourself. Usually you don't do that though. You just use a UINavigationController or UITabBarController as your rootViewController and allow them to manage getting the events to new "pushed" view controllers, or you popup view controllers with "presentModalViewController".

How to have a UIButton action inside a NavigationController's view call the controllers delegate?

I have my main program with MainAppDelegate.h,MainAppDelegate.m.
I have created two custom navigation controllers ANavController, BNavController classes and have created added the controllers in Interface Builder and assigned my custom classes to the two controllers inside the MainWindow.xib
When the application first loads I make it render the first NavControllers and its view in the didFinishLaunchingWithOptions method:
[window addSubView:ANavController.view];
This is works fine and loads the first navigation controllers view. My problem is that within the view on each nav controller, inside the viewDidLoad method I have created a UIBarButtonItem which I add to the right side of the navcontroller.
I'm trying to make this button call an action method defined inside my MainAppDelegate.m.
For both of my two custom NavController classes I have set the delegate to MainAppDelegate inside interface builder. I try to define buttons like so:
[flipButton addTarget:self.delegate action:#selector(changeModeAction:)
forControlEvents:UIControlEventTouchUpInside];
and obviously then inside MainAppDelegate.m I have defined a method:
-(void)changeModeAction:(id)sender
This method should flip the ANavigationController currently in the window to he BNavigationController.
But it obviously crashes on the addTarget:self.delegate. What's the proper way to do this?
Basically I'm trying to add a button to the top right of each NavControl which will fire a FLIP page animation, switching to the other NavController and it's stack.
So if you're two levels deep on ANavController and you hit the top right button, it will flip to BNavController and wherever you were last in it's stack. Hitting the button again will flip the page again back to ANavController and you'll still be two levels deep, before you switched to B. Does this make sense?
I think my idea implementation needs some work?
Sorry for posting this as an answer instead of a comment - my reputation is too low to add comments - but could you please provide the error message?
EDIT: See thread below for details - the problem was that 'self' was not a subclass of UINavigationController and therefore did not have a delegate property. Changing this to self.navigationController.delegate worked.