delegation and passing data back from childViewController

 ̄綄美尐妖づ 提交于 2019-12-12 06:55:08

问题


I have been struggling with this for a few days and have received valuable help on the way from S.O. I have made the simplest possible project to reduce the possibilities of it being a typo. All my project is, is a ViewController that holds a container view hooked to a childViewController. The "parent" ViewController is set as the delegate of the childViewController. In the viewDidLoad of the child I am passing a value which is just a string. This string should be passed on to the parent and printed on the console. Here are the files.

ViewController.h

#import <UIKit/UIKit.h>
#import "ChildViewController.h"

@interface ViewController : UIViewController <ChildViewControllerDelegate>

@end

ViewController.m

#import "ViewController.h"

@interface ViewController ()

@property NSString *myValueRetrieved;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

   ChildViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:@"ChildVC"];

    controller.delegate = self;

    NSLog(@"Here is my value: %@",self.myValueRetrieved);
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}

- (void) passValue:(NSString *)theValue{

    self.myValueRetrieved = theValue;
}

@end

ChildViewController.h

#import <UIKit/UIKit.h>

@protocol ChildViewControllerDelegate;

@interface ChildViewController : UIViewController

@property (weak)id <ChildViewControllerDelegate> delegate;

@end

@protocol ChildViewControllerDelegate <NSObject>

- (void) passValue:(NSString*) theValue;

@end

ChildViewController.m

#import "ChildViewController.h"

@interface ChildViewController ()
@property NSArray *colors;
@end

@implementation ChildViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    [self.delegate passValue:@"Hello"];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}

@end

Am I right to think that when the app is launched, the console should log the following message: "here is my value: hello". Am I doing something wrong in terms of logically not getting delegation or is it just a silly typo somewhere? tx


回答1:


You're assuming that the view is loaded when the view controller is instantiated. That's now how it works. The view gets loaded when it's needed (like to add to the parent view).

But you can force the view to load and make this work. Call -loadViewIfNeeded on the child view controller right after setting the delegate. That will probably get you what you want:

controller.delegate = self;
[controller loadViewIfNeeded];
NSLog(@"Here is my value: %@",self.myValueRetrieved);

Or, if you do want to call back the delegate in viewDidLoad, then you'd need to move the NSLog to the -passValue: method, since the primary view controller's viewDidLoad method will have already finished running.




回答2:


To do this make ParentController a delegate of ChildController. This allows ChildController to send a message back to ParentController enabling us to send data back.

For ParentController to be delegate of ChildController it must conform to ChildController's protocol which we have to specify. This tells ParentController which methods it must implement.

In ChildController.h, below the #import, but above @interface you specify the protocol.

@class ChildController;

@protocol ViewControllerBDelegate <NSObject>
- (void)addItemViewController:(ChildController *)controller didFinishEnteringItem:(NSString *)item;
@end

next still in the ChildController.h you need to setup a delegate property and synthesize in ChildController.h

@property (nonatomic, weak) id <ChildControllerDelegate> delegate;

In ChildController we call a message on the delegate when we pop the view controller.

NSString *itemToPassBack = @"Pass this value back to ParentController";
[self.delegate addItemViewController:self didFinishEnteringItem:itemToPassBack];

That's it for ChildController. Now in ParentController.h, tell ParentViewController to import Child and conform to its protocol.

import "ChildController.h"

@interface ParentController : UIViewController In ParentController.m implement the following method from our protocol

- (void)addItemViewController:(ChildController *)controller didFinishEnteringItem:(NSString *)item
{
    NSLog(@"This was returned from ChildController %@",item);
}

The last thing we need to do is tell ChildController that ParentController is its delegate before we push ChildController on to nav stack.

ChildController *ChildController = [[ChildController alloc] initWithNib:@"ChildController" bundle:nil];
ChildController.delegate = self
[[self navigationController] pushViewController:ChildController animated:YES];


来源:https://stackoverflow.com/questions/34983566/delegation-and-passing-data-back-from-childviewcontroller

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