在Cocoa Mac OSX中设置FirstResponder的问题
为了学习可可,我正在一个小应用程序中工作,并且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。但它仍然无法正常工作。
你正在做这比它需要更难。
在Interface Builder中,将窗口的initialFirstResponder
出口指向您的文本字段。
就是这样。
如果你绝对必须以编程方式做到这一点,使用:
[window setInitialFirstResponder:yourTextField];
请记住,如果你与可可的战斗做一些事情,似乎应该是简单的,那么你很可能就错了。
只是阅读文档:
becomeFirstResponder
通知接收器,它是即将成为 第一个响应者在其NSWindow。
[...]
使用NSWindow makeFirstResponder:方法,没有这种方法,使 对象的第一个响应者。永远不要直接调用这个方法。
谢谢,我试过使用:FakturaAppDelegate * appDelegate =(FakturaAppDelegate *)[[NSApplication sharedApplication] delegate]; [appDelegate.window makeFirstResponder:self.invoiceCredit];而不是成为FirstResponder,它仍然不起作用。 –
问题在于,在applicationDidFinishLaunching退出之后,self.view.window在第一个视图控制器的viewDidLoad方法中为null。因此,becomeFirstResponder在viewDidLoad中不起作用。尝试延迟所述第一应答器的设定,如下所示:
[_yourTextField performSelector:@selector(becomeFirstResponder) withObject:无afterDelay:0。1];
你不应该尝试设置第一个响应者在viewDidLoad中方法,因为窗口是在这一点上仍然为零。用viewWillAppear代替:
- (void)viewWillAppear
{
[super viewWillAppear];
if (!_started) {
_started = YES;
[self.view.window makeFirstResponder:_yourView];
}
}
苹果也曾经说过你不应该直接调用becomeFirstResponder。使用[yourWindow makeFirstResponder:yourView];代替。
你说得对。这个话题应该很久以前就已经关闭了,这个问题在6年前发布时是相关的。 API现在不同了,反正这也是错误的方法。 ;) –
我刚刚添加了这个答案,以帮助与可可问题的其他人。 – Borzh
重写viewDidAppear,并在该方法内调用NSTextField的becomeFirstResponder方法。
请注意,在我自己的工作中,无论使用NSTextField的becomeFirstResponder方法还是NSWindow的makeFirstResponder方法,viewWillAppear已被证明对于所述调用来说为时尚早。
当窗口首先打开时,文本字段未加载。根据用户在窗口中单击哪个按钮,会加载五个不同的视图。所以这就是为什么我必须将焦点放在适当的文本字段。 –