在Cocoa Mac OSX中设置FirstResponder的问题

时间:2011-08-31 21:13:00

标签: objective-c cocoa nstextfield first-responder becomefirstresponder

我正在研究一个小应用程序只是为了学习可可,我很难将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]; 而不是成为第一个响应者。但它仍然无效。

5 个答案:

答案 0 :(得分:2)

你正在努力实现这一目标。

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

就是这样。

如果您绝对必须以编程方式执行此操作,请使用:

[window setInitialFirstResponder:yourTextField];

请记住,如果你和Cocoa打架做一些看起来应该很简单的事情,那么你可能做错了。

答案 1 :(得分:2)

覆盖viewDidAppear,并在所述方法中调用NSTextField的becomeFirstResponder方法。

请注意,在我自己的工作中,无论是使用NSTextField的becomeFirstResponder方法还是使用NSWindow的makeFirstResponder方法,viewWillAppear对于所述调用来说都太早了。

答案 2 :(得分:0)

麻烦的是,在applicationDidFinishLaunching退出之前,self.view.window在第一个视图控制器的viewDidLoad方法中为null。因此,becomeFirstResponder在viewDidLoad中不起作用。尝试延迟第一响应者的设置,如下所示:

  

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

答案 3 :(得分:0)

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

import email
print(email.policy)
AttributeError: 'module' object has no attribute 'policy'

from email import policy
print(email.policy)
<module 'email.policy' from 'C:\\Anaconda3\\lib\\email\\policy.py'>
Apple曾经说过,你永远不应该直接调用becomeFirstResponder。请改用 [yourWindow makeFirstResponder:yourView];

答案 4 :(得分:-2)

请阅读文档:

  

<强> becomeFirstResponder

     

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

     

[...]

     

使用NSWindow makeFirstResponder:方法,而不是此方法   第一响应者的对象。永远不要直接调用此方法。