1

Recently read this:

Passing Data between View Controllers

Which outlines delegate setup between two controllers. The problem I am running into is that I do not have a segue between the controllers. And I am not sure I wan ta segue between those two controllers, ie I do not want to change the view when a value updates, behind the scenes I just want another controller to be aware that the value did indeed change.

This is the step I am stumbling on from the link above:

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

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

I am not using nibs, nor do I think a prepare for segue is the correct place to wire the delegate up. Is there some other place I am supposed to wire up the delegate?

here is my code: SettingsVeiwController, want to let another controller know when the user updates the refresh rate field.

#import <UIKit/UIKit.h>

@protocol SettingsViewControllerDelegate <NSObject>
-(void) didUpdateRefreshRate:(NSString *)refreshRate;
@end

@interface SettingsViewController : UITableViewController <UITextFieldDelegate>

@property (weak, nonatomic) IBOutlet UITextField *refreshRateTextField;

@property (copy, nonatomic) NSNumber *refreshRate;

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

@end

MainViewController, want to get updates when refreshRate changes,

@interface MainViewController ()

@end

@implementation MainViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

-(void) didUpdateRefreshRate:(NSString *)refreshRate {
    NSLog(@"This was returned from SettingsViewController %@",refreshRate);
}

@end

I think everything is setup correctly to work except telling SettingsViewController that the MainViewController is its delegate.

Probably most important is that this is a tabbed application. MainViewController is one tab, SettingsViewController is another. Might be a good way to set this up when using a tabbed application, ie how do I pass info/data between tabs. I assume it via delegates still just need to know where to wire them together.

Cœur
  • 37,241
  • 25
  • 195
  • 267
lostintranslation
  • 23,756
  • 50
  • 159
  • 262
  • Neither of the view controllers are invisible. Bad explanation I guess. I was trying to say that when a user sets a new refesh rate in the SettingsViewController that there is no transition to the MainViewController, only that the MainViewController was aware that a change had been made. – lostintranslation May 20 '13 at 17:56
  • Ah, that makes a lot more sense! Thanks for the explanation. – Sergey Kalinichenko May 20 '13 at 18:01

1 Answers1

1

A good place would be MainViewController viewDidLoad (assuming that MainViewController has nothing to do with the presentation of SettingsViewController). You just need to get the instance of SettingsViewController and set its delegate to self.

That said, I'm going to assume that SettingsViewController is presented after MainViewController, so no instance of SettingsViewController exists when MainViewControllers view is loaded. In that case, whichever controller has the responsibility of creating and presenting an instance of SettingsViewController needs to do something to tell MainViewController that it has done so. A good solution to this would be notifications as you want to keep cross coupling low and not teach this class about the requirements of MainViewController.

Define your own notification name:

#define SettingsViewControllerWasCreatedNotification @"SettingsViewControllerWasCreatedNotification"

Setup MainViewController as an observer:

- (void)viewDidLoad
{
    [super viewDidLoad];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(settingViewControllerShown:)
                                                 name:SettingsViewControllerWasCreatedNotification
                                               object:nil];
}

After SettingsViewController is created, post the notification

[[NSNotificationCenter defaultCenter] postNotificationName:SettingsViewControllerWasCreatedNotification
                                                    object:settingsViewController];

The new settings view controller is the object. Now, your MainViewController will receive the callback and can add itself as the delegate:

- (void)settingViewControllerShown:(NSNotification *)note
{
    SettingsViewController *settingsViewController = (SettingsViewController *)[note object];
    settingsViewController.delegate = self;
}
Wain
  • 118,658
  • 15
  • 128
  • 151
  • Forget to mention this is a tabbed application. There is probably a place to setup delegates between tabs but I am not 100% sure. I.E. main is one tab, settings is another. – lostintranslation May 20 '13 at 19:01
  • Where are all of the view controllers for the tabs created? There is no 'standard place' for setting up delegation, you set them up where you have the data (when the view controller is created above) or you make the data available when you have it (which is the notification method above). – Wain May 20 '13 at 19:04
  • Shouldn't the application setup the tabs somewhere. Seems like that is where I can tell the SettingsViewController that it has a delegate for the MainViewController. – lostintranslation May 20 '13 at 19:24
  • It must setup the tabs somewhere or they wouldn't exist :) Are you setting them up in a storyboard / XIB or code ? – Wain May 20 '13 at 19:33
  • Storyboard. Found this, http://enroyed.com/ios/how-to-pass-data-between-ios-tab-bars-using-delegate/. Almost working ;) All is setup and compiles delegate method never gets called. – lostintranslation May 20 '13 at 20:42
  • Breakpoint to ensure the delegate is set when you try to use it. – Wain May 20 '13 at 21:20