NSTextfield + NSMenu 和第一响应者
我正在尝试实现我自己的自动补全系统(结果是从 sqlite 数据库中提取)
我已经设置了一个 NSTextField 和适当的委托。每次 NSTextField 中的文本发生变化时,它都会调用 - (void)controlTextDidChange:(NSNotification *)aNotification
方法
它工作正常,在这个方法中我以编程方式构建一个菜单,最后我调用/显示它该代码:
NSRect frame = [address frame];
NSPoint menuOrigin = [[address superview] convertPoint:NSMakePoint(frame.origin.x, frame.origin.y+frame.size.height-25)
toView:nil];
NSEvent *event = [NSEvent mouseEventWithType:NSLeftMouseDown
location:menuOrigin
modifierFlags:NSLeftMouseDownMask // 0x100
timestamp:0
windowNumber:[[address window] windowNumber]
context:[[address window] graphicsContext]
eventNumber:0
clickCount:1
pressure:1];
[NSMenu popUpContextMenu:menu withEvent:event forView:address];
其中address
是我的NSTextField
,menu
是我的NSMenu
。 问题是菜单占据焦点,因此您只能在文本字段中输入 1 个字母,然后您无法再输入文本,因为菜单现在是第一响应者。
我的问题是如何显示菜单并将文本字段保留为第一响应者,以便您可以在字段中每次文本更改时重新加载菜单时键入它。
事实上,它应该像 Safari 或 chrome 地址栏一样。
I'm trying to implement my own autocomplemention system (result is pull from an sqlite database)
I've set up a NSTextField and the appropriate delegate. Each time the text in the NSTextField change, it call - (void)controlTextDidChange:(NSNotification *)aNotification
method
It work fine, in this method I build a menu programtically and finally I call/show it with that code:
NSRect frame = [address frame];
NSPoint menuOrigin = [[address superview] convertPoint:NSMakePoint(frame.origin.x, frame.origin.y+frame.size.height-25)
toView:nil];
NSEvent *event = [NSEvent mouseEventWithType:NSLeftMouseDown
location:menuOrigin
modifierFlags:NSLeftMouseDownMask // 0x100
timestamp:0
windowNumber:[[address window] windowNumber]
context:[[address window] graphicsContext]
eventNumber:0
clickCount:1
pressure:1];
[NSMenu popUpContextMenu:menu withEvent:event forView:address];
Where address
is my NSTextField
and menu
is my NSMenu
.
The problem is that the menu take the focus, so you can type only 1 letter in the text field and then you can't type text anymore because the menu is now the first responder.
My questions is how to show the menu and keep the text field as first responder so you can type in it while the menu is reloaded at each text change in the field.
It should be like in Safari or chrome address bar in fact for example.
我不相信 NSMenu 可以做到这一点。 NSMenu 的实现是由系统在相当低的级别控制的,它被设计为获取键盘焦点。您需要创建自己的视图或窗口,它看起来有点像菜单,但不使用 NSMenu。例如,请注意 chrome 地址栏中的菜单看起来不像标准 NSMenu。您需要创建一个将显示和绘制的视图,并接收回调或通知以在用户键入时进行更新,但不会获取键盘焦点。 NSView(实际上是 NSResponder)上有一些方法可以控制视图是否接受第一响应者状态。
I don't believe this is possible with NSMenu. NSMenu implementation is controlled by the system at a quite low level, and it is designed to take keyboard focus. What you need is to create your own view, or window, that looks somewhat like a menu, but is not using NSMenu. Notice for example that that the menu in the chrome address bar does not look like a standard NSMenu. You need to create a view that will appear and draw, and receive callbacks or notifications to update as the user types, but will not take keyboard focus. There are methods on NSView (NSResponder actually) that control whether a view accepts first responder status.