0

I've been following this example to help me build a delegate but unfortunately I've missed something so it is not working for me. How do I set up a simple delegate to communicate between two view controllers?

My code looks like this:

//  HintsViewController.h

#import <UIKit/UIKit.h>

@protocol HintDelegateProtocol;

@interface HintsViewController : UIViewController

@property (weak, nonatomic) id<HintDelegateProtocol> hintDelegate;

-(IBAction)showFirstLetter:(id)sender
-(IBAction)showHint:(id)sender;
-(IBAction)showAnswer:(id)sender;

@end

@protocol HintDelegateProtocol <NSObject>

-(void)HintsViewController:(HintsViewController*)hintsViewController
                showFirstLetter:(NSString*)firstLetter;


-(void)HintsViewController:(HintsViewController*)hintsViewController
           showHint:(NSString*)hint;


-(void)HintsViewController:(HintsViewController*)hintsViewController
           showAnswer:(NSString*)answer;

@end

//
//  HintsViewController.m

#import "HintsViewController.h"

@implementation HintsViewController

#pragma mark -
#pragma mark IBActions

/* As per a suggestion below I changed the code here /*

- (IBAction)showHint:(id)sender
{
     [self.hintDelegate HintsViewController:self showHint:@"Hint"];
}

- (IBAction)showFirstLetter:(id)sender
{
   [self.hintDelegate HintsViewController:self showFirstLetter:@"FirstLetter"];

}

- (IBAction)showAnswer:(id)sender
{
    [self.hintDelegate HintsViewController:self showAnswer:@"Answer"];
}

@end

And then in the a Controller class I have the following:

//
//  GameLogicController.h

#import "HintsViewController.h"

@interface GameLogicController : NSObject < HintDelegateProtocol>

@end

And in the implementation I have the following:

//  GameLogicController.m
-(void) nextRiddle 
{
        HintsViewController *hintsViewController = [[HintsViewController alloc] init];
        hintsViewController.hintDelegate = self;
}

#pragma mark -
#pragma mark HintsFunctionality

-(void)HintsViewController:(HintsViewController*)hintsViewController
           showFirstLetter:(NSString*)firstLetter
{
    NSLog(@"Show First Letter called");
}


-(void)HintsViewController:(HintsViewController*)hintsViewController
                  showHint:(NSString*)hint
{
    NSLog(@"show Hint called");
}


-(void)HintsViewController:(HintsViewController*)hintsViewController
                showAnswer:(NSString*)answer
{
     NSLog(@"Show answer called");
}

Using breakpoints I can see that the IBActions in the HintsViewController are being called, but putting a breakpoint in any of the delegate methods in the gameLogicController are never hit. So I have missed an important step in setting up the connection between the GameLogicController and the HintsViewController. Can anyone help me spot it?

Community
  • 1
  • 1
Linda Keating
  • 2,215
  • 7
  • 31
  • 63
  • Try to change property (weak, nonatomic) to property (strong, nonatomic) – Andrey Sep 06 '15 at 22:19
  • Change [strongDelegate HintsViewController:self showFirstLetter:@"firstLetter"]; to [self.hintDelegate HintsViewController:self showFirstLetter:@"firstLetter"] (actually you don't need line before it) – Andrey Sep 06 '15 at 22:24
  • Just today I posted some simple code with delegate, you can take a look: https://github.com/asaptf/ALAnimatedButtonWithMenu – Andrey Sep 06 '15 at 22:24
  • I'll take a look. I tried your suggestion but still the delegate methods aren't firing in the GameLogicController. – Linda Keating Sep 06 '15 at 22:27
  • 2
    in `nextRiddle` you are allocating a new, local `HintsViewController` instance and setting the delegate, but then you don't do anything with it (such as presenting it) so as soon as that method ends the hints view controller will be deallocated. You need to set the delegate on the instance of the view controller that is actually presented on screen – Paulw11 Sep 06 '15 at 22:35
  • Ok that makes sense. I'm not sure how to solve it, but at least it makes sense to me what is going wrong. – Linda Keating Sep 06 '15 at 22:39
  • 1
    @Paulw11 thankyou. I figured out how to fix it thanks to your answer. When I instantiated the HintsViewController I set the delegate as follows: HintsViewController *hintsVC = [storyBoard instantiateViewControllerWithIdentifier:@"hintsViewController"]; hintsVC.hintDelegate = self.controller; – Linda Keating Sep 06 '15 at 22:47

1 Answers1

0

Say you have two files: one is your ViewController, and other is your ConnectionManager Class.

Declare protocol and its methods in your ConnectionManager class, and define your protocol methods in the ViewController class. By setting the delegate of your ConnectionManager class in ViewController Class, you can call your Protocol method.

@protocol ConnManagerDelegate<NSObject>

- (void)didReceiveData:(NSDictionary *)data;
- (void)didFailWithError:(NSError*)error;

@end

@interface ConnectionManager : NSObject<NSURLConnectionDelegate>

@property(nonatomic,assign)id< ConnManagerDelegate > delegate;

And elseswhere in the same file .m, when your response comes just call

[Self.delegate didReceiveData:mDict];

In the ViewController file after you alloc init ConnectionManager class, set its delegate to self and define the protocol methods. It is these methods you will have your response from ConnectionManager class.

This is all Protocol Delegation pattern

buruzaemon
  • 3,847
  • 1
  • 23
  • 44