Reputation: 1233
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
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
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