我正在研究一个小应用程序只是为了学习可可,我很难将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]; 而不是成为第一个响应者。但它仍然无效。
答案 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:方法,而不是此方法 第一响应者的对象。永远不要直接调用此方法。