4

爲了學習可可,我正在一個小應用程序中工作,並且Im很難將FirstResponder設置爲某些NSTextFields。在Cocoa Mac OSX中設置FirstResponder的問題

當視圖打開時,我想要選擇第一個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]代表]; [appDelegate.window makeFirstResponder:self.invoiceCredit]; 而不是成爲FirstResponder。但它仍然無法正常工作。

回答

2

你正在做這比它需要更難。

在Interface Builder中,將窗口的initialFirstResponder出口指向您的文本字段。

就是這樣。

如果你絕對必須以編程方式做到這一點,使用:

[window setInitialFirstResponder:yourTextField]; 

請記住,如果你與可可的戰鬥做一些事情,似乎應該是簡單的,那麼你很可能就錯了。

+0

當窗口首先打開時,文本字段未加載。根據用戶在窗口中單擊哪個按鈕,會加載五個不同的視圖。所以這就是爲什麼我必須將焦點放在適當的文本字段。 –

-2

只是閱讀文檔:

becomeFirstResponder

通知接收器,它是即將成爲 第一個響應者在其NSWindow。

[...]

使用NSWindow makeFirstResponder:方法,沒有這種方法,使 對象的第一個響應者。永遠不要直接調用這個方法。

+0

謝謝,我試過使用:FakturaAppDelegate * appDelegate =(FakturaAppDelegate *)[[NSApplication sharedApplication] delegate]; [appDelegate.window makeFirstResponder:self.invoiceCredit];而不是成爲FirstResponder,它仍然不起作用。 –

0

問題在於,在applicationDidFinishLaunching退出之後,self.view.window在第一個視圖控制器的viewDidLoad方法中爲null。因此,becomeFirstResponder在viewDidLoad中不起作用。嘗試延遲所述第一應答器的設定,如下所示:

[_yourTextField performSelector:@selector(becomeFirstResponder) withObject:無afterDelay:0。1];

0

你不應該嘗試設置第一個響應者在viewDidLoad中方法,因爲窗口是在這一點上仍然爲零。用viewWillAppear代替:

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

蘋果也曾經說過你不應該直接調用becomeFirstResponder。使用[yourWindow makeFirstResponder:yourView];代替

+0

你說得對。這個話題應該很久以前就已經關閉了,這個問題在6年前發佈時是相關的。 API現在不同了,反正這也是錯誤的方法。 ;) –

+0

我剛剛添加了這個答案,以幫助與可可問題的其他人。 – Borzh

1

重寫viewDidAppear,並在該方法內調用NSTextField的becomeFirstResponder方法。

請注意,在我自己的工作中,無論使用NSTextField的becomeFirstResponder方法還是NSWindow的makeFirstResponder方法,viewWillAppear已被證明對於所述調用來說爲時尚早。