2

EDITED I have .xib file with UIView. UIView contains some elements and tap gesture recognizer.

It is connected to AnnotationView with outlets. In AnnotationView, I am catching tap events and it works fine.

Then I am trying to pass this event to my parent view (ViewController), where AnnotationView instance was created and added as subview. But my delegate method is not getting called. I don't know, how to solve this problem, and I don't know if it is because I am using subview or I am just doing something wrong with delegate.

Here is some code:

AnnotationView.h

#import <UIKit/UIKit.h>

@protocol protName <NSObject>

-(void) test;

@end

@interface AnnotationView : UIView

@property (strong, nonatomic) IBOutlet UIImageView *image;
@property (weak, nonatomic) IBOutlet UILabel *textLabel;
@property (weak, nonatomic) IBOutlet UILabel *accessoryLabel;
@property (strong, nonatomic) IBOutlet UITapGestureRecognizer *tapRecognizer;
@property (nonatomic, weak) id <protName> delegate;

-(IBAction)handleTap:(UITapGestureRecognizer *)tapRecognizer;
@end

AnnotationView.m

#import "AnnotationView.h"

@implementation AnnotationView


- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
        NSArray *nibContents = [[NSBundle mainBundle] loadNibNamed:@"AnnotationView"
                                                             owner:self
                                                           options:nil];
        AnnotationView *_myView = [nibContents objectAtIndex:0];
        _myView.backgroundColor = [UIColor greenColor];
        [self addSubview: _myView];

    }
    return self;
 }

-(IBAction)handleTap:(UITapGestureRecognizer *)tapRecognizer{
    NSLog(@"tap tap");

    [self.delegate test]; //this delegate is nil
}

@end

ViewController.h

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

@interface ViewController : UIViewController <protName>
@property (nonatomic,retain) AnnotationView *annot;

-(void) test;

@end

ViewController.m

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad
{
    _annot = [[AnnotationView alloc] initWithFrame:CGRectMake(100, 100, 212, 45)];
    _annot.textLabel.text = @"some text";
    _annot.delegate = self;
    [self.view addSubview:_annot];
}
-(void) viewWillAppear:(BOOL)animated{
    _annot.delegate = self;
}
-(void) test{
    NSLog(@"Delegate massage is received!");
}
@end
  • 1
    It's very weird to me that you're loading a UIView subclass, that in turn loads a UIView subclass that is hooked up from a nib, and adding that as a subview. Am I seeing this right? – Daddy Aug 08 '13 at 13:28
  • I'm new to objective-c and this solution for adding subview i've found somwhere on stackoverflow and you seeing it right, it works that way... and "tap tap" is the only thing which is working... – user2199890 Aug 08 '13 at 13:35
  • It almost looks recursive, but I don't know if loading from a nib will call `-initWithFrame` – Daddy Aug 08 '13 at 13:35
  • Edited question. There was a small typo. 'UIView' with labels, image and tap recognizer are created in 'AnnotationView.xib' file, if this matters. – user2199890 Aug 08 '13 at 13:52
  • I don't see the error here. Make sure you're not clearing the `delegate` property. – Marcus Adams Aug 08 '13 at 14:26
  • I see it now. When you load the initial AnnotationView in `viewDidLoad`, that object, inside its `initWithFrame` method creates another AnnotationView that sets its delegate to `self`. The thing you are tapping on is one of the two AnnotationView objects, and it is intercepting the touch event. My answer is what fixes this problem. – Daddy Aug 08 '13 at 14:48

3 Answers3

1

How to use delegate in correct way!

In SecondViewController.h:

   @protocol messageDelegate <NSObject>
    @optional
    -(void) test;
    @end
    @interface SecondViewController : NSString
    @property (nonatomic, assign) id <messageDelegate> delegate;
    @end

In SecondViewController.m:

-(void)readyToSend
{
    [self.delegate test];

}

In ViewController.h:

@interface ViewController : UIViewController<messageDelegate>
@end

In ViewController.m: in

- (void)viewDidLoad {
SecondViewController *secondViewController = [[SecondViewController alloc] init];
secondViewController.delegate = self;
}
-(void) test{
NSLog(@"Delegate massage is received!");

}

Hope it will help!

user2545330
  • 408
  • 4
  • 17
1

Why not just do this:

@implementation ViewController

- (void)viewDidLoad
{
    CGRect frame = CGRectMake(100, 100, 212, 45)];
    NSArray *nibContents = [[NSBundle mainBundle] loadNibNamed:@"AnnotationView"
                                                         owner:nil
                                                       options:nil];
    for (id object in nibContents) {
        if ([object isKindOfClass:[AnnotationView class]]) {
            _annot = (AnnotationView *)object;
        }
    }        
    _annot.frame = frame;
    _annot.backgroundColor = [UIColor greenColor];
    _annot.textLabel.text = @"some text";
    _annot.delegate = self;
    [self.view addSubview:_annot];
}
Daddy
  • 9,045
  • 7
  • 69
  • 98
  • This code gives error '[ setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key image.'. – user2199890 Aug 08 '13 at 13:48
  • change the `owner:` parameter from `self` to `nil` – Daddy Aug 08 '13 at 14:22
  • Ok now delegate is working, but i was forced to delete all elements from my .xib file view because the error was still appear. So now i'm gonna solve this new problem. Thank you a lot. – user2199890 Aug 08 '13 at 14:31
  • The second issue was not so difficult so now all works fine. I spent 6 hours to make this code work and You fix it for 5 min. Thank you again!!! – user2199890 Aug 08 '13 at 14:36
  • Glad this fixed it. Hope it clears it up so you understand why it works. It's hard for me to explain why because I am having trouble wrapping my mind around it myself. It makes sense for me to do it this way. I'd also like to point you to a change up in my code, with the `for()` loop – Daddy Aug 08 '13 at 14:43
0

It is your viewController not the AnnotationView that implements the protocol. So you could move that to give:

@interface AnnotationView : UIView <protName>
Marcus Adams
  • 53,009
  • 9
  • 91
  • 143
David Elliman
  • 1,379
  • 8
  • 15