Question

I was wondering if it possible to find which view called the following function

- (void)viewWillAppear:(BOOL)animated {
  //find here the name of the calling view
}

Is there any way to find which view called the new view?

Was it helpful?

Solution 4

Needless to say, "views" don't call this, but rather iOS will call this when your view appears. And unfortunately, this is complicated because you might get viewWillAppear because some other view controller presented this view controller's view, or you might get this when a view controller presented by this view was dismissed or popped (depending upon modal vs push).

We can probably outline all sorts of sophisticated and complicated ways of solving this problem, but we should probably first step back and ask why you need to do this. What are you really trying to achieve? If you're just trying to coordinate interaction between view controllers, there are far better ways of doing that (e.g. delegates, setting view controller properties, etc.).


Update:

If you're trying to figure out whether the data has changed, rather than relying upon some "where did I come from" logic, I'd personally lean towards some mechanism where those data-modifying controllers or processes bear the responsibility for notifying your view controller of this fact.

The simplest way of doing that would be to employ a delegate design pattern, where your child view controller would have a delegate property, which is a pointer to your controller that needs to know about the data change, and the child controller would simply invoke that method when data has changed. In slightly more complicated scenarios, you might combine this delegate pattern with a formal delegate protocol (so that the child view controller doesn't need to know anything about the parent controller other than the fact that it conforms to a particular protocol), but some may say that this is not needed when just communicating between two specific and well-known view controllers. See Using Delegation to Communicate with Other Controllers in the View Controller Programming Guide.

In complicated situations (e.g. data could be changing in a variety of places or even asynchronously, for example during updates via a web service), I'll use the notifications design pattern, in which the view controller will add itself as an observer of a particular notification to be sent by the NSNotificationCenter and whenever the data is updated, the notification center will be told to post that particular notification, which will, in turn, be received by the observer, your view controller.

OTHER TIPS

In viewWillAppear directly not. If it's pushed on a UINavigationController, you can get the viewControllers and get the previous one.

if (self.navigationController){
NSArray* viewControllers = self.navigationControllers.viewControllers;
UIViewController* lastViewController = [viewControllers objectAtIndex:([viewControllers count] - 1)];
NSLog(@"%@ is my last ViewController before navigationg to this ViewController", lastViewController);
}

Well if are using the navigation controller you can get the array of viewControllers which are pushed by:

 NSArray *array =  self.navigationController.viewControllers;

but this will give you the view controllers which has been pushed it will fail if are coming back from a view ie popped from navigation stack as in both case your

- (void)viewWillAppear:(BOOL)animated {
  //find here the name of the calling view
  }

will be called.

You can use presentingViewController for this, but the problem is this will return the memory address of the view controller rather than the name of the pointer.

One solution would be to assign a tag to the view property of the presenting view controller and then ask for that tag in your second controller:

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    NSLog(@"%i",[[[self presentingViewController] view] tag]);
}

In your first view controller:

[[self view] setTag:(someNSInteger)];
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top