4

我正在开发一个小应用程序只是为了学习可可,而且我很难将 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。但它仍然不起作用。

4

5 回答 5

3

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

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

而已。

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

[window setInitialFirstResponder:yourTextField];

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

于 2011-08-31T23:51:21.463 回答
2

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

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

于 2017-11-27T12:34:51.403 回答
0

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

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

苹果也曾经说过,你永远不应该直接调用 becomeFirstResponder。使用[yourWindow makeFirstResponder:yourView]; 反而。

于 2017-05-10T01:45:13.867 回答
0

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

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

于 2016-12-24T03:43:09.553 回答
-1

只需阅读文档:

成为第一响应者

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

[...]

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

于 2011-08-31T22:31:40.520 回答