Alex
Alex

Reputation: 1233

Having issues with custom delegate

I am trying to implement a simple delegate and seem to be having some problems. The intended result is for the user to press a button in a UIView that is linked to a UIViewController via Outlet. I also use the UISearchBarDelegate which works just fine. I am only having a problem with my custom delegate method being called.

MainViewController.h:

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

@interface MainViewController : UIViewController <UISearchBarDelegate, catFilterDelegate>

@property (strong, nonatomic) IBOutlet UIView *switchViewOutlet;

// Instance Methods
- (void)searchBarLoad;

@end

MainViewController.m:

#import "MainViewController.h"

@interface MainViewController ()

@end

@implementation MainViewController

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

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.

    CategoryFilterView *temp = [[CategoryFilterView alloc] initWithFrame:CGRectMake(0, 0, 320, 50)];
    temp.delegate = self;
    self.switchViewOutlet = temp;
    [self.view addSubview:self.switchViewOutlet];
}

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

- (void)searchBarLoad {
    UISearchBar *search = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, 320, 50)];
    search.delegate = self;
    search.showsCancelButton = YES;

    self.switchViewOutlet = search;
    [self.view addSubview:self.switchViewOutlet];

}

- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
    [self.switchViewOutlet removeFromSuperview];
    CategoryFilterView *temp = [[CategoryFilterView alloc] initWithFrame:CGRectMake(0, 0, 320, 50)];
    temp.delegate = self;
    self.switchViewOutlet = temp;
    [self.view addSubview:self.switchViewOutlet];
}

- (void)searchPressed {
    // Custom Delegate Method
    NSLog(@"Test"); // This is never called
    [self.switchViewOutlet removeFromSuperview];
    [self searchBarLoad];
}

@end

CategoryFilterView.h:

#import <UIKit/UIKit.h>

@protocol catFilterDelegate <NSObject>

- (void)searchPressed;

@end

@interface CategoryFilterView : UIView

// Button Outlets
@property (strong, nonatomic) IBOutlet UIButton *byMeButtonOutlet; // Linked in .xib
@property (strong, nonatomic) IBOutlet UIButton *byFriendsButtonOutlet; // Linked in .xib
@property (strong, nonatomic) IBOutlet UIButton *searchButtonOutlet; // Linked in .xib

// Delegate
@property (assign, nonatomic) id<catFilterDelegate> delegate;

// Button Actions
- (IBAction)searchPressAction:(id)sender; // Linked with UIButton from .xib file

@end

CategoryFilterView.m:

#import "CategoryFilterView.h"

@implementation CategoryFilterView

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code        
        NSArray *subviewArray = [[NSBundle mainBundle] loadNibNamed:@"CategoryFilterView" owner:self options:nil];
        UIView *mainView = [subviewArray objectAtIndex:0];
        [self addSubview:mainView];    }
    return self;
}

- (IBAction)searchPressAction:(id)sender {
    NSLog(@"Test"); // This gets called when the user presses the button from MainViewController
    [self.delegate searchPressed];
}
@end

I can supply more information if needed.

Upvotes: 1

Views: 385

Answers (2)

rdelmar
rdelmar

Reputation: 104082

I'm not sure exactly how you have things set up, but this it what worked for me. In the CategoryFilterView.xib, I made a view with a button which was connected to the IBAction searchPressAction: in the CategoryFilterView.m file. I deleted the init code in that file (so the only code is that action method). I set MainViewController the file's owner in the CategoryFilterView xib. Then in the MainViewController, I had this code to add the subview:

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    self.subviewArray = [[NSBundle mainBundle] loadNibNamed:@"CategoryFilterView" owner:self options:nil];
    UIView *mainView = [self.subviewArray objectAtIndex:0];
    CategoryFilterView *temp = (CategoryFilterView *)mainView;
    temp.delegate = self;
    self.switchViewOutlet = temp;
    [self.view addSubview:self.switchViewOutlet];
}

You would have to add similar code to the searchBarCancelButtonClicked: method to get the view back again.

After Edit:

It's not clear to me that you need to use a delegate at all. If you make MainViewController the file's owner of the view in the nib, then you can connect any buttons in that view to IBActions in MainViewController.m directly, without using a delegate. In that case you also don't need to subclass that view -- it can just be a UIView.

Upvotes: 1

rooster117
rooster117

Reputation: 5552

It is a good practice to see if your delegate responds to the selector you are trying to call.

I would recommend calling it with the following code:

if([self.delegate respondsToSelector:@selector(searchPressed)])
{
    NSLog(@"My delegate is not nil");
    [self.delegate searchPressed];
}

This will tell you if your delegate is set correctly. A big possibility is that your delegate is nil but if you call a selector on a nil object it won't crash but won't do anything.

Upvotes: 2

Related Questions