Question

I ultimately want to write an iOS app incorporating ALAssetsLibrary, but as a first step toward understanding delegation, I'm trying to pass a simple message between two view controllers. For some reason, I can't seem to get the message to pass. In particular, the delegate object (derpy) doesn't appear to exist (if(self.derpy) returns NO)).

I asked the same question on the Apple forums and was told that I should be using segues and setting properties / calling methods using self.child instead, but that seems strange. If I were to pass messages using the parent / child properties, would I still be able to create my views in Interface Builder? Once I have my two views set up, say inside a UINavigationController, I'm not sure how to actually "wire them up" so I can pass messages between them. Sorry if the question is overly broad.

Here's the controller I'm declaring the protocol in (called PickerViewController):

Interface:

#import <UIKit/UIKit.h>
#import <AssetsLibrary/AssetsLibrary.h>

@protocol DerpDelegate <NSObject>
@required
- (void) test;
@end

@interface PickerViewController : UIViewController

@property (nonatomic, assign) id<DerpDelegate> derpy;

@end

Implementation:

   #import "PickerViewController.h"

    @interface PickerViewController ()   
    @end

    @implementation PickerViewController

    - (void)viewDidLoad
   {
        [super viewDidLoad];      
        if (self.derpy) {         // If the delegate object exists
            [self.derpy test];    // send it this message 
        } else {
            NSLog(@"Still not working.");     // This always returns (i.e., self.derpy doesn't exist)
        }
    }

Delegate controller (MainViewController) interface:

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

@interface MainViewController : UIViewController <DerpDelegate> // public promise to implement delegate methods
@property (strong, nonatomic) PickerViewController *picker;

- (void) test;

@end

And lastly, the delegate controller (MainViewController) implementation:

#import "MainViewController.h"
#import "PickerViewController.h"

@interface MainViewController ()
@end

@implementation MainViewController

// Here's that method I promised I'd implement

- (void) test{ 
    NSLog(@"Test worked.");     // This never gets called
}

- (void)viewDidLoad {
    [super viewDidLoad];
    self.picker.derpy = self;

//lazy instantiation
- (PickerViewController *) picker{
if(!_picker) _picker = [[PickerViewController alloc]init];
return _picker;
}

EDIT: Many thanks to rydgaze for pointing me in the right direction with self.picker.derpy = self, but for some reason, things still aren't working properly. Importantly, once that property has been set, if(self.picker.derpy) returns YES from MainViewController. But if(self.derpy) is still returning NO when called from inside the PickerViewController's viewDidLoad. How can the property exist and not exist at the same time?

Was it helpful?

Solution

You need to be sure that you're setting the delegate on the instance of the view controller that you put on screen. If you're using a navigation controller and segues to go between MainViewController and PickerViewController, then you should set the delegate in prepareForSegue:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    self.picker = (PickerViewController *)segue.destinationViewController;
    self.picker.derpy = self;
}

OTHER TIPS

You need to populate the delegate first.

Basically, your MainViewController shoudl at somepoint do a

picker.derpy = self;

Then when the delegate fires in PickerViewController, the callback will happen.

Edit: A good practice is to do something like in PickerViewController

@property (nonatomic, assign) id<DerpDelegate > derpy;

and in your MainViewController indicate that you will implement the delegate

@interface MainViewController : UIViewController<DerpDelegate>

Eventually in your implementation of MainViewController

You will have something like

picker = [[PickerViewController alloc]init];
picker.derpy = self;
[picker doYourThing];

Once picker is all done, it may want to return results using the delegate.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top