我正在尝试实现一个简单的委托,似乎遇到了一些问题。预期结果是用户可以通过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
如果需要,我可以提供更多信息。
答案 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。