在 Cocoa Mac OSX 中设置 FirstResponder 的问题

Posted

技术标签:

【中文标题】在 Cocoa Mac OSX 中设置 FirstResponder 的问题【英文标题】:Problems setting FirstResponder in Cocoa Mac OSX 【发布时间】:2011-08-31 21:13:00 【问题描述】:

我正在开发一个小应用程序,只是为了学习可可,而且我很难将 FirstResponder 设置为一些 NSTextFields。

当视图打开时,我希望选择第一个 NSTextField,clientNumber,所以我在 loadView 方法的末尾触发 [clientNumber becomeFirstResponder],但它没有选择文本字段。 但是,当我单击触发 (IBAction)addToArray 方法的按钮时,它会选择正确的文本字段。此外,我还有另一个文本字段,它应该只包含整数,所以我有一个粗略的验证。当内容不是 int 时,我会发出哔哔声,就像它应该的那样,但它没有选择文本字段。

这是我的代码:

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil

    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) 
      NSLog(@"initWithNibName");
    
    return self;


- (void)viewWillLoad 
    NSLog(@"viewWillLoad");


- (void)viewDidLoad 
    NSLog(@"viewDidLoad");
    [self initNewInvoice];    


- (void)loadView 
    NSLog(@"loadView");
    [self viewWillLoad];
    [super loadView];
    [self viewDidLoad];
    FakturaAppDelegate *appDelegate = (FakturaAppDelegate *)[[NSApplication sharedApplication] delegate]; 
    [appDelegate.window makeFirstResponder:self.clientNumber]; 


- (void)awakeFromNib

    NSLog(@"awakeFromNib");


- (IBAction)saveInvoice:(id)sender

    FakturaAppDelegate *appDelegate = (FakturaAppDelegate *)[[NSApplication sharedApplication] delegate]; 
    [appDelegate.window makeFirstResponder:self.invoiceCredit]; 


- (IBAction)addToArray:(id)sender

    [clientNumber setStringValue: @"Toodeloo"];
    FakturaAppDelegate *appDelegate = (FakturaAppDelegate *)[[NSApplication sharedApplication] delegate]; 
    [appDelegate.window makeFirstResponder:self.clientNumber];  


- (IBAction)updateCreditDays:(id)sender

    if(invoiceCredit.intValue)
        [self updateCredit];
    else
        NSBeep();
        FakturaAppDelegate *appDelegate = (FakturaAppDelegate *)[[NSApplication sharedApplication] delegate]; 
    [appDelegate.window makeFirstResponder:self.invoiceCredit]; 
    

我真的希望有人可以在这里帮助我。

编辑:

我错了,谢谢你的指点,但是当我修复代码时,使用这个: FakturaAppDelegate *appDelegate = (FakturaAppDelegate *)[[NSApplication sharedApplication] delegate]; [appDelegate.window makeFirstResponder:self.invoiceCredit]; 而不是成为FirstResponder。但是还是不行。

【问题讨论】:

【参考方案1】:

你让这件事变得比需要的困难得多。

在 Interface Builder 中,将窗口的 initialFirstResponder 出口设置为指向您的文本字段。

就是这样。

如果您绝对必须以编程方式进行,请使用:

[window setInitialFirstResponder:yourTextField];

请记住,如果您正在与 Cocoa 争吵做一些看起来应该很简单的事情,那么您可能做错了。

【讨论】:

第一次打开窗口时没有加载文本字段。根据用户在窗口中单击的按钮,将加载五个不同的视图。所以这就是为什么我必须稍后将焦点设置到适当的文本字段。 不适用于 SplitViewControllers 之类的东西。在 viewDidAppear 中以编程方式设置它【参考方案2】:

重写viewDidAppear,并在该方法中调用NSTextField的becomeFirstResponder方法。

请注意,在我自己的工作中,无论是使用 NSTextField 的 becomeFirstResponder 方法还是使用 NSWindow 的 makeFirstResponder 方法,viewWillAppear 都被证明太早了。

【讨论】:

【参考方案3】:

问题是 self.view.window 在第一个视图控制器的 viewDidLoad 方法中为空,直到 applicationDidFinishLaunching 退出。因此,becomeFirstResponder 在 vi​​ewDidLoad 中不起作用。尝试延迟第一响应者的设置,如下所示:

[_yourTextField performSelector:@selector(becomeFirstResponder) withObject:nil afterDelay:0.1];

【讨论】:

【参考方案4】:

您不应该尝试在 viewDidLoad 方法中设置第一响应者,因为此时 window 仍然为零。改用 viewWillAppear:

- (void)viewWillAppear

    [super viewWillAppear];
    if (!_started) 
        _started = YES;
        [self.view.window makeFirstResponder:_yourView];
    

Apple 也曾经说过,你永远不应该直接调用 becomeFirstResponder。请改用 [yourWindow makeFirstResponder:yourView];

【讨论】:

你说得对。。这个话题应该早就关闭了,这个问题在6年前发布时是相关的。 API 现在不同了,无论如何这都是错误的方法。 ;) 我刚刚添加了这个答案来帮助其他人解决 Cocoa 问题。【参考方案5】:

只需阅读文档:

成为第一响应者

通知接收者它即将成为 NSWindow 中的第一响应者。

[...]

使用 NSWindow makeFirstResponder: 方法,而不是这个方法,使 第一响应者的对象。切勿直接调用此方法。

【讨论】:

谢谢,我尝试使用:FakturaAppDelegate *appDelegate = (FakturaAppDelegate *)[[NSApplication sharedApplication] delegate]; [appDelegate.window makeFirstResponder:self.invoiceCredit];而不是成为FirstResponder,它仍然不起作用。 这拯救了我的一天,+1

以上是关于在 Cocoa Mac OSX 中设置 FirstResponder 的问题的主要内容,如果未能解决你的问题,请参考以下文章

sh 使用HomeBrew在Mac OSX中设置Golang。在zshell,fish或bash中设置`GOPATH`和`GOROOT`变量。

sh 使用HomeBrew在Mac OSX中设置Golang 1.5。在zshell或bash中设置`GOPATH`和`GOROOT`变量。

sh 使用HomeBrew在Mac OSX中设置Golang 1.5。在zshell或bash中设置`GOPATH`和`GOROOT`变量。

Objective C - 创建 PDF (Mac OSX / Cocoa)

在 Swift、Cocoa、Mac OSX 中将 EXIF 数据设置为 NSImage

如何修改 Mac OS X Cocoa 布局约束