1

So I'm trying to get a hang of using delegates, and I've watched a few tutorials on how to use them so far. I still find them confusing and after trying to implement one myself, have an issue that I can't seem to solve.

I have two ViewControllers, the first one ViewController contains a UITextField *sampleTextField and a button with the method switchViews. It also contains the protocol declaration with the method sendTextToViewController. SwitchViews is also linked to a segue that switches to the SecondViewController. In SecondViewController the only object is a UILabel *outputLabel When the user taps the button, it calls switchViews and the view changes to SecondViewController, and upon loading outputLabel should be changed to whatever text was entered in sampleTextField in ViewController. However the delegate method sendTextToViewController is never being called. All objects are created in Interface Builder.

Here is the code to make it a bit easier to understand:

ViewController.h

#import <UIKit/UIKit.h>

@protocol TextDelegate <NSObject>

-(void)sendTextToViewController:(NSString *)stringText;

@end

@interface ViewController : UIViewController

- (IBAction)switchViews:(id)sender;

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

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

@end

Then declared this in ViewController.m

- (IBAction)switchViews:(id)sender {
    NSLog(@"%@", self.sampleTextField.text);
    [self.delegate sendTextToViewController:self.sampleTextField.text];
}

SecondViewController.h

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

@interface SecondViewController : UIViewController <TextDelegate>

@property (weak, nonatomic) IBOutlet UILabel *outputLabel;


@end

SecondViewController.m

#import "SecondViewController.h"

@interface SecondViewController ()

@end

@implementation SecondViewController
@synthesize outputLabel;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {

    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    ViewController *vc = [[ViewController alloc]init];
    [vc setDelegate:self];
}

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

-(void)sendTextToViewController:(NSString *)stringText
{
    NSLog(@"Sent text to vc");
    [outputLabel setText:stringText];
}

I've looked at this and the first answer makes sense, but for some reason it's not working.

I do think that the problem is where I am setting calling [vc setDelegate:self], but not sure how to fix this. Some pointers in the right direction would be greatly appreciated. Keep in mind I'm new to obj-c so if you can explain what you are saying, that would be great. Thank you.

Albert K
  • 25
  • 7

2 Answers2

0

Your are creating a new instance of ViewController but you don't do anything with it.

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    ViewController *vc = [[ViewController alloc]init];
    [vc setDelegate:self];
}

The SecondViewController needs to have reference to the FirstViewController to be able to set itself as a delegate.

lucianomarisi
  • 1,552
  • 11
  • 24
  • Ahh ok. To make a reference, [I'd have to do something like this](http://stackoverflow.com/questions/9099961/objective-c-getting-a-uiviewcontroller-reference) I assume? But I don't have parent/child structure so I'd have to set the viewcontroller differently. EDIT: Wait, pretty sure I can do this when presenting viewcontroller2 – Albert K Jun 15 '14 at 20:00
  • That should work but since you mentioned you've set up a segue to push the `SecondViewController` you could use the `prepareForSegue` method to retrieve the `destinationViewController` (i.e. your `SecondViewController`). Check this question http://stackoverflow.com/questions/7864371/ios-how-to-pass-prepareforsegue-an-object – lucianomarisi Jun 15 '14 at 20:03
  • Yep, got it working with `self.delegate = secondVC;` after setting destination vc. Thanks so much!! – Albert K Jun 15 '14 at 20:10
  • I'm wondering how exactly would I do this without segues? Since I don't have a parent/child structure I can't use the method that I linked, I'd have to do something different like declaring a @property for the ViewController2, and then somehow using that property in ViewController. Hmm. Any ideas? – Albert K Jun 15 '14 at 20:44
  • If you didn't use segues, you may be pushing the `SecondViewController` on the navigation stack from the `FirstViewController` at which point you would set the delegate. – lucianomarisi Jun 15 '14 at 20:46
  • By navigation stack I assume you mean the point where I present `SecondViewController`, which would make sense but what if I have a `ScrollView` that has a hide/unhide toggle and it loads up with the main View. Over the past few days I've been studying delegates to attempt to implement something in my main project. I'm using cocos2d for this and so this might be a bit different in regards to classes and all. If you have any experience with cocos2d, [here is the question I asked a while back](http://stackoverflow.com/questions/23819273/how-to-change-labels-text-from-a-button-on-a-ccscrollview) – Albert K Jun 15 '14 at 21:53
0

First you don't have to use delegation to do such a program. A simpler way would be just creating a property in the SecondViewController that you'll pass the content of the textField into it.

Your code doesn't work because you called sendTextToViewController on a delegate that hasn't been set. You have set the delegate to a new instance of ViewController, not the one presented onscreen.

Noam Solovechick
  • 1,127
  • 2
  • 15
  • 29