gubbfett
gubbfett

Reputation: 2177

Calling a parent UIViewControllers function

Okay, I have a problem and has not been able to find what I'm doing wrong.

I have a UIVievController with a view and some functions and stuff. One is to open (from a button in a actionsheet) another UIVeiwController. Looks like this:

PersonalSettings *personalSettings;
-(IBAction) displaySettingsMenu:(id)sender
{
    personalSettings = [[PersonalSettings alloc] 
                        initWithNibName:@"PersonalSettings" 
                        bundle:nil];
    [self.view addSubview:personalSettings.view];
    [SettingsSheet dismissWithClickedButtonIndex:0 animated:YES];
}

This works like a charm and I can make som updates in this view. When I close this view all the settings are updated properly and the view disappears, but what I want to do is to reload the parent ViewController (View?) so I can see the new settings I've made. I have a void function for this in the parent, but how can I call it? When the save-button is hit in the child ViewController I remove the view with:

[self.view removeFromSuperview];

What I have to do from here is to call the update function from the child view for the parent view.

I found some code for this, but with the exception "superclass" instead of "superview" since superview does not appears in the list. Looks like this:

[self.view removeFromSuperview];

MainViewController *Parent = (MainViewController *)self.superclass;
[Parent updateView];

Is there something "magic" I can do to say something like "reload parent view"?

I hope I've made the problem understandable. :)

EDIT:

Really thanks you gyus, i'm closer now. I'm not 100% sure how this delegate thing works (yet) but i'm close to a solution. Actually, i realized don't even have to run a method, just update a label.

From the child, i have written this:

MainViewController* Parent = [[MainViewController alloc] init];
Parent.delegate = self;
Parent.TheLabel.text = @"foo";

...but this does not work - even if it really finds the label and every thing. And if i from the child tries this:

NSLog(@"Parent label: %@", Parent.TheLabel.text);

it logs "Parent label: (null)".

But, however, i can reach the update function from the child now and it runs. The problem is that this function takes values from other labels (in the parent view) and this is where it crashes - they all say null when i run the function from the child. Even if their not. Any ideas why?

Upvotes: 0

Views: 875

Answers (4)

gubbfett
gubbfett

Reputation: 2177

Since i'm just a newbe and added the child view as "addSubview" i had theese problems. Changing the view with - (void)presentModalViewController:(UIViewController *)modalViewController animated:(BOOL)animated did the trick! Thanks any way an specially thanks to kubi :)

Upvotes: 1

sergio
sergio

Reputation: 69047

If you are looking for a generic way to access the parent of a given controller, have a look at this method:

+ (YOURTABBARCONTROLLER*)parentTabBarController:(UIResponder*)view {
    id nextResponder = nil;
    id v = view;
    while (nextResponder = [v nextResponder]) {
         if ([nextResponder isKindOfClass:[YOURTABBARCONTROLLER class]])
            return nextResponder;
         v = nextResponder;
    }
    return nil;
 }

It will navigate the responder chain to give you back the first class of a given type that is found there. You could have YOURTABBARCONTROLLER as UIViewController, or specify your concrete controller class to have more control. So, you would say, e.g.:

 YOURTABBARCONTROLLER* parent = [self parentTabController:self.view];

(if self is your child controller and you defined the above method in it).

This is the closest thing you can get to, AFAIK. The method could also be made into a category of UIViewController, so you always have it there.

EDIT:

If you use the +, then call the method like this: [CLASSNAME parentTabController:view], where CLASSNAME is the class where you defined it. Anyway, you can use the - in the method declaration, and it will work with self as described.

If it does not work for you, please post the full method, as you defined it, and the exact way you call it. You might also add this line:

           NSLog(@"Found Responder: %@", nextResponder); //-- ADDED THIS

as the first line in the while loop, so that the method will log what it finds in the responder chain.

Upvotes: 0

cayden
cayden

Reputation: 81

i agree with aeoliant, using delegate model might be more approapriate. a simple exlanation here Working with delegate in objective-c

Upvotes: 0

aeoliant
aeoliant

Reputation: 387

If you are familiar with the delegate model, then make your parent view the delegate and pass information back that way from the child. You'll find some good docs about it on the Apple website.

Basically you add a 'delegate' field to your child's 'constructor' ie:

child = [[ViewController alloc] initWithDelegate:this withNibName:@"myNib"];

Then, in the child class, when you receive information, you can access fields/methods in your delegate.

- (void) volumeDidChange:(int)volume
{
    delegate.volume = volume
}

or something like that. good luck!

Upvotes: 1

Related Questions