UIViewController parentViewController access properties

无人久伴 提交于 2019-12-05 04:17:11

问题


I know this question has been asked several times and I did read existing posts on this topic but I still need help.

I have 2 UIViewControllers - parent and child. I display the child UIViewController using the presentModalViewController as below:

ChildController *child = 
 [[ChildController alloc] initWithNibName:@"ChildView" bundle:nil];
[self presentModalViewController:child animated:YES];
[child release];

The child view has a UIPickerView. When user selects an item from UIPickerView and clicks done, I have to dismiss the modal view and display the selected item on a UITextField in the parent view.

In child's button click delegate, I do the following:

ParentController *parent = 
 (ParentController *)[self.navigationController parentViewController];
[parent.myTextField setText:selectedText];
[self dismissModalViewControllerAnimated:YES];

Everything works without errors. But I don't know how to load the parent view so that it displays the updated UITextField.

I tried

[parent reloadInputViews];

doesn' work. Please help.


回答1:


Delegation is the way to go. I know some people that may be looking for an easier solution but trust me I have tried others and nothing works better than delegation. So anyone having the same problem, go read up on delegation and follow it step by step.

In your subviewcontroller.h - declare a protocol and declare delegate mthods in it.

@protocol myDelegate
 -(void)clickedButton:(subviewcontroller *)subController;
@end

In your subviewcontroller.h, within @interface:

id<myDelegate> delegate;
@property (nonatomic, assign) id<myDelegate> delegate;    
NSString *data;
-(NSString *)getData;

In your subviewcontroller.m, synthesize myDelegate. Add the following code to where you want to notify your parentviewcontroller that the subview is done doing whatever it is supposed to do:

 [delegate clickedButton:self];

and then handle getData to return whatever data you want to send to your parentviewcontroller

In your parentviewcontroller.h, import subviewcontroller.h and use it's delegate

 #import "subviewcontroller.h"
 @interface parentviewcontroller : VUIViewController <myDelegate>
 {}

In your parentviewcontroller.m, implement the delegate method

 - (void)clickedButton:(subviewcontroller *)subcontroller
 {
   NSString *myData = [subcontroller getData];
   [self dimissModalViewControllerAnimated:YES];
   [self reloadInputViews];
 }

Don't forget memory management!




回答2:


If a low-memory warning comes in during your modal view's display, the parent's view will be unloaded. Then parent.myTextField is no longer referring to the right text field until the view is reloaded. You can force a reload of the view just by calling parent.view;

However, a better idea might be to have the parent view have a String property that can be set by the child view. Then, when the parent view reappears, put that data into the text field, inside viewWillAppear: for example. You'd want to have the value set to some default value for when the parent view initially shows up too.




回答3:


-(void) viewWillAppear:(BOOL) animated doesn't get called for me either, exactly when it's a modal view controller. No idea why. Not incorrectly overridden anywhere in this app, and the same problem occurs on the other 2 apps I'm working on. I really don't think it works.

I've used the delegate approach before, but I think that following approach is pretty good as well.

I work around this by adding a private category to UIViewController, like so:

.h file:

@interface UIViewController(Extras)
// returns true if this view was presented via presentModalViewController:animated:, false otherwise.
@property(readonly) BOOL isModal;
// Just like the regular dismissModalViewController, but actually calls viewWillAppear: on the parent, which hasn't been working for me, ever, for modal dialogs.
- (void)dismissModal: (BOOL) animated;
@end

and .m file:

@implementation UIView(Extras)
-(BOOL) isModal
{
    return self == self.parentViewController.modalViewController;
}

- (void)dismissModal: (BOOL) animated
{
    [self.parentViewController viewWillAppear: animated];
    [self dismissModalViewControllerAnimated: animated];
}
@end

which I can now call like this when I want to dismiss the dialog box:

// If presented as a modal view, dismiss yourself. 
if(self.isModal)
    [self dismissModal: YES];

and now viewWillAppear is correctly called.

And yes, I'm donating a bonus 'isModal' property, so that the modal view can tell how it was being presented, and dismiss itself appropriately.



来源:https://stackoverflow.com/questions/2412688/uiviewcontroller-parentviewcontroller-access-properties

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!