iPhone编程中的选择器

iPhone编程中的选择器,iphone,cocoa-touch,Iphone,Cocoa Touch,我正在创建一个视图控制器,用于输入文本信息 视图本身由一个标签、文本字段和导航栏中的两个按钮组成:“取消”和“确定” 当用户按下“取消”时,我只是跳回根视图控制器 但当他按下OK时,我想首先从根视图控制器调用一个函数,然后再弹出 我试图通过以下方式实现它: 标题: @interface UserInputViewController : UIViewController { UILabel *textLabel; UITextField *textField; SEL

我正在创建一个视图控制器,用于输入文本信息

视图本身由一个标签、文本字段和导航栏中的两个按钮组成:“取消”和“确定”

当用户按下“取消”时,我只是跳回根视图控制器

但当他按下OK时,我想首先从根视图控制器调用一个函数,然后再弹出

我试图通过以下方式实现它:

标题:

@interface UserInputViewController : UIViewController {
    UILabel *textLabel;

    UITextField *textField;

    SEL OKButtonAction;
}

-(NSString*) getEnteredText;

-(UserInputViewController*) initWithTitle: (NSString*)title Text: (NSString*)text andOKButtonSelector: (SEL) OKButtonSelector;

@end
实施:

@implementation UserInputViewController

-(UserInputViewController*) initWithTitle: (NSString*)title Text: (NSString*)text andOKButtonSelector: (SEL) OKButtonSelector
{
    self = [self init];
    self.title = title;

    OKButtonAction = OKButtonSelector;

    textLabel = [ [UILabel alloc] initWithFrame: CGRectMake(20, 20, 280, 50)];
    [textLabel setText: text];
    [ [self view] addSubview: textLabel];

    textField = [ [UITextField alloc] initWithFrame: CGRectMake(20, 100, 280, 50)];
    [ [self view] addSubview: textField];

    return self;
}

-(NSString*) getEnteredText
{
    return [textField text];
}

-(void) popToRootViewController
{
    [ [self navigationController] popToRootViewControllerAnimated: YES ];
}

-(void) popToRootWithOKAction
{
    [ [self navigationController] popToRootViewControllerAnimated: YES ];
    [self performSelector: OKButtonAction];
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    //Cancel button
    UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] initWithTitle: NSLocalizedString(@"cancel button", @"") style: UIBarButtonSystemItemCancel target: self action: @selector(popToRootViewController) ];


    [ [self navigationItem] setLeftBarButtonItem: cancelButton animated: NO];
    [cancelButton release];

    //OK button
    UIBarButtonItem *OKButton = [[UIBarButtonItem alloc] initWithTitle: NSLocalizedString(@"ok button", @"") style: UIBarButtonSystemItemSave target: self action: @selector(popToRootWithOKAction) ];

    [ [self navigationItem] setRightBarButtonItem: OKButton animated: NO];
    [OKButton release];

}
下面是根视图控制器方法:

-(void) OKButtonAction
{
    NSLog(@"text: %@", [newProfileDialog getEnteredText]);
    [newProfileDialog release];
}

-(void) add_clicked {
    newProfileDialog = [ [UserInputViewController alloc] initWithTitle: @"User name" Text: @"Please enter a new user name:" andOKButtonSelector: @selector(OKButtonAction)];

    [ [self navigationController] pushViewController: newProfileDialog animated: YES];
}
但是,当我编译它并从按下的视图中按下OK按钮时,我得到一个异常

我还不熟悉选择器编程,所以我很难找出我做错了什么

我怎样才能达到这个目标


谢谢。

[self-performAction:OKButtonAction]将调用对象上的OKButtonAction选择器。最有可能的情况是,您希望对一名代表进行调用。虽然这将起作用:

[[self.navigationController rootViewController]性能选择器:OK按钮操作]

这不是大多数框架实现它的方式。我建议的两种方法是:

  • 添加一个“id target;”实例变量,并将其传递到init方法中。然后您可以使用[delegate performSelector:OKButtonAction]。这将使视图控制器与根视图控制器解耦,允许您在其他情况下也使用此视图控制器 我将考虑使用委托和A而不是使用选择器,而不是“目标”。这将为您提供措辞强硬的方法,例如在其他委托(如UITableViewDelegate)中找到的方法

您尝试执行的操作称为“委派”-确定按钮的操作委派给另一个对象,在本例中为根控制器。尝试将视图控制器的初始值设定项更改为:

-(UserInputViewController*) initWithTitle:(NSString*)title Text:(NSString*)text delegate:(id)delegate;
将委托存储在实例变量(无需保留)和
PoptorootWithOkaAction
call中:

if([delegate respondsToSelector:@selector(OKButtonAction)])
    [delegate performSelector:@selector(OKButtonAction)];
委托方法甚至不需要在根控制器的.h文件中声明。在
UserInputViewController
的头文件中,只需添加第二个
@界面

@interface NSObject (UserInputViewControllerDelegate)
    -(void)OKButtonAction;
@end

我建议阅读苹果网站上Objective-C编程语言文档中的

除非你做了大量的内省,否则没有理由将选择器声明为变量。只要需要,就使用
@selector()
指令来创建它