get the Previous modal view controller - iphone

I have 4 view controllers: VC1,VC2,VC3,VC4.
VC4 can be called from VC1,VC2,VC3, my point is how to get which one of view controller (VC1,VC2,VC3) has called VC4?

Flohei's answer is right, but a bit long winded given there's already a method to do this in iOS. There's no real need to add another property. You can use the parentViewController property to find out which view controller is currently displaying your modal controller.

You could add a UIViewController property to VC4 and set this one every time you create a VC4 instance to the current viewController.

Related

iOS: Call method in tabs viewController

I'm trying to come up with something simple, but i can't figure it out.
I have a UITabBarController and at one point I have to display another tab's UIViewController, and call a method in that new UIViewController, using data from the original UIViewController.
So basically I want to pass data to another UIViewController (that may not be initialized yet), and show the right tab.
If I use NSNotificationCenter, I'm not sure if the tab's UIViewController is initialized yet, and also it's a bit ugly to use delegation here.
What is a clean way to send and show data in the new tab?
A better idea would be to have a protocol implemented in the tab view controller the view controller can call to send data and set up any other view controller
You should have a data model of some sort (singleton?) that is accessible by both view controllers. When the second view controller is about to display its view, it should reference the data model to determine the data it should display.
int x = 1; //this is the view controller you want to go to.
MySecondViewController *secondViewController = (MySecondViewController *)self.tabBarController.viewControllers[x];
[secondViewController setDataObject:dataObject];
[self.tabBarController setSelectedIndex:x];
So what's happening is you're calling the controller from the tabBarController, it will initiate there if its not. Then you can set whatever you want on the controller, then you just switch to the selected tab.

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 tell if view has appeared via popping or not?

Using a UINavigationViewController, how do I find out how a view has appeared?
The view has either appeared in a straightforward manner, as the first view in the UINavigationController stack. Or it has appeared because a second view has been popped and the first view has revealed itself again. How do you find out which of these happened?
The only reliable way to do this, as far as I'm aware, is to subclass UINavigationController and override the UINavigationBarDelegate methods:
– navigationBar:shouldPushItem:
– navigationBar:didPushItem:
– navigationBar:shouldPopItem:
– navigationBar:didPopItem:
Don't forget to call super, of course.
Simple approach is to add a property to your RootViewController to track whether or not it has pushed another view onto the navigationController.
-(BOOL)hasPushedSecondView;
Initialize to NO in your init method.
Before pushing secondViewControllers view onto the stack, update the property to YES.
In viewWillAppear, check the value and update your view accordingly. Depending on how you want the application to behave you may need to reset the hasPushedsecondview property back to NO.
you could take a look at the leftBarButtonItem or backBarButtonItem, based on how your application is written and determine how the view appeared. If it is on top, unless you have a custom leftBarButtonItem, there would be no object there.
You can determine this directly via a couple of methods on your UIViewController subclass.
From Apple's documentation:
Occasionally, it can be useful to know why a view is appearing or
disappearing. For example, you might want to know whether a view
appeared because it was just added to a container or whether it
appeared because some other content that obscured it was removed. This
particular example often appears when using navigation controllers;
your content controller’s view may appear because the view controller
was just pushed onto the navigation stack or it might appear because
controllers previously above it were popped from the stack.
The UIViewController class provides methods your view controller can
call to determine why the appearance change occurred.
isMovingFromParentViewController: view was hidden because view controller was removed from container
isMovingToParentViewController: view is shown because it's being added to a container
isBeingPresented: view is being shown because it was presented by another view controller
isBeingDismissed: view is being hidden because it was just dimissed