0

I am using storyboard and I would like that when the user clicks on a certain button (SwapViewAndTriggerMethod), the view changes to another one (SecondView) defined by a second view controller and then a certain method (MyMethod) present in SecondView.m is called. I am using the code below and this successfully takes me to the other view....but MyMethod does not get called. How can I achieve this please? Cheers!

- (IBAction) SwapViewAndTriggerMethod:(id)sender
{
UIViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:@"SecondView_storyboard"];

[self presentViewController:controller animated:YES completion:nil];

[instanceOfGS2controlller MyMethod:nil];
}

This is the error I get: Warning: Attempt to present on < SecondView_ViewController: 0x13f634f60> whose view is not in the window hierarchy! Note: MyMethod calls a picker to select a photo and assign it to an image view.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
jeddi
  • 651
  • 1
  • 12
  • 21
  • In the storyboard is the view controller with that identifier pointing to an instance of that object/View Controller? Also, when assigning `controller`s type, I'd suggest setting it to whatever your `UIViewController`s subclass name is instead of just `UIViewController` – mittens Apr 28 '14 at 20:02
  • This is the error I get: Warning: Attempt to present on < SecondView_ViewController: 0x13f634f60> whose view is not in the window hierarchy! Note: MyMethod calls a picker to select a photo and assign it to an image view. – jeddi Apr 28 '14 at 20:48

3 Answers3

1

You can't call the method which presents a picker view controller from the other controller like that, because as the error says, SecondView_ViewController's view isn't in the window hierarchy yet. You could set a flag in SwapViewAndTriggerMethod:, and use that in viewDidAppear of SwapViewAndTriggerMethod: to present the picker,

- (IBAction) SwapViewAndTriggerMethod:(id)sender {
    SecondView_ViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:@"SecondView_storyboard"];
    [self presentViewController:controller animated:YES completion:nil];
    controller.presentPicker = YES; // presentPicker is a BOOL property that you need to add to SecondView_ViewController
}

Then, in SecondView_ViewController, do this,

-(void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    if (self.presentPicker) 
        // present your picker here
    self.presentPicker = NO;
}
rdelmar
  • 103,982
  • 12
  • 207
  • 218
  • I have defined a BOOL presentPicker in SecondView_ViewController but when I compile it says: Property 'presentPicker' not found on object of type 'SecondView_ViewController *' – jeddi Apr 29 '14 at 05:23
  • @jeddi, did you declare that property in the .h file? – rdelmar Apr 29 '14 at 05:31
  • Yes I did. @interface SecondView_ViewController : UIViewController { BOOL presentPicker; } – jeddi Apr 29 '14 at 05:50
  • @jeddi, that's not a property, that's an ivar the way you declared it. So either create a property, or refer to your ivar as "presentPicker" not "self.presentPicker". – rdelmar Apr 29 '14 at 05:53
  • Thanks. I'm slowly getting there.. I've added @property (nonatomic, assign) BOOL presentPicker; in h. and synthesised it in m. But it doesn't work... :-( – jeddi Apr 29 '14 at 07:44
  • @jeddi, what doesn't work? What result are you getting, and are you getting any errors now? – rdelmar Apr 29 '14 at 15:26
  • Well, I don't get any errors at all, but simply "if (self.presentPicker)" is never seen as YES or TRUE. Surely I have implemented the BOOL property wrong, but I don't know what else should I do apart from declaring it in h as BOOL presentPicker, then adding @property (assign) BOOL presentPicker; and finally synthesising it in m... On the view controller where I have the method "- (IBAction) CustomizeTargetAppearance:(id)sender" I have simply imported the header of the other class and nothing else. – jeddi Apr 30 '14 at 15:27
  • @jeddi, you don't need to use "@synthesize" any more, and it's better not to. Also, don't create an ivar as well as the property -- the only thing you should have in the .h is "@property (assign) BOOL presentPicker;" – rdelmar Apr 30 '14 at 15:35
  • Hi rdelmar. Thanks for your support. ivar removed and "@synthesize" also removed. Like before, no errors, but self.presentPicker is never TRUE and the method does not get called! – jeddi Apr 30 '14 at 15:45
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/51762/discussion-between-rdelmar-and-jeddi) – rdelmar Apr 30 '14 at 15:48
  • Problems solved thanks to an amazing support form rdelmar! I had the code "if (self.presentPicker)" in viewDidLoad rather than in viewDidAppear as suggested! Many thanks! – jeddi Apr 30 '14 at 16:49
0

a few things

1.when your presenting a new viewController, it's life cycle begins, meaning it's ViewDidLoad (and other functions) are called, so you can call your function there

2.generally, you can use NSNotificationCenter to post messages across your app, but i'm not sure it's your best option here

eiran
  • 1,378
  • 15
  • 16
  • Regarding option 1: I cannot have the method to be always triggered in ViewDidLoad. I would like it to be triggered only when the method in the other view is called... – jeddi Apr 28 '14 at 20:42
  • can you explain why? maybe you can save a value in userDefaults that states whether you need to call the function or not – eiran Apr 29 '14 at 14:28
  • Because I want the user to be able to switch to that view without calling that method and at the same time switching to that view from another one AND having that method called. I know I could save a flag in NSUserdefauls for this purpose but I am looking for a better way of communication between classes. I have no experience using NSNotificationCenter, but again probably it's not the best way of interacting between classes. Thanks anyway for your help – jeddi Apr 30 '14 at 15:30
0

If you are having the method called when another view's method is called, you have two options: (1) make the function publicly accessible iOS: How to define public methods?, or (2) use -(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender and call the method in view did load.

Community
  • 1
  • 1
kjbradley
  • 335
  • 2
  • 4
  • 20