自定义委托有问题

时间:2013-02-06 16:48:05

标签: ios objective-c

我正在尝试实现一个简单的委托,似乎遇到了一些问题。预期结果是用户可以通过UIView按下UIViewController中与Outlet相关联的按钮。我也使用UISearchBarDelegate,效果很好。我只调用了自定义委托方法的问题。

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

如果需要,我可以提供更多信息。

2 个答案:

答案 0 :(得分:2)

最好查看您的代理是否响应您要拨打的选择器。

我建议使用以下代码调用它:

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

这将告诉您代理是否设置正确。一个很大的可能性是你的委托是nil,但是如果你在一个nil对象上调用一个选择器它就不会崩溃但不会做任何事情。

答案 1 :(得分:1)

我不确定你是如何设置的,但这对我有用。在CategoryFilterView.xib中,我使用一个连接到IBAction searchPressAction的按钮创建了一个视图:在CategoryFilterView.m文件中。我删除了该文件中的init代码(因此唯一的代码是该操作方法)。我在MainFilterView xib中为MainViewController设置了文件的所有者。然后在MainViewController中,我有了这段代码来添加子视图:

- (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];
}

您必须在searchBarCancelButtonClicked:方法中添加类似的代码才能重新获取视图。

编辑后:

我不清楚您是否需要使用代理人。如果您将MainViewController作为nib中视图的文件所有者,那么您可以直接将该视图中的任何按钮连接到MainViewController.m中的IBActions,而无需使用委托。在这种情况下,您也不需要对该视图进行子类化 - 它可以只是一个UIView。