如何接受编辑和关闭包含自定义视图的弹出菜单?

tro*_*foe 10 macos cocoa objective-c nsmenu nsview

我希望在我的表视图中编辑特定列时添加使用日期选择器的功能,并使用此处的代码片段,该代码片段运行良好.但是NSDatePicker不适合我的需要所以我使用自己的自定义视图,使用IB创建并通过NSViewController子类加载来编辑日期.

但我无法弄清楚如何关闭该弹出式菜单中接受编辑,即回报的方式YESuserAcceptedEdit:

BOOL userAcceptedEdit = [menu popUpMenuPositioningItem:nil
                                            atLocation:frame.origin
                                                inView:tableView];
Run Code Online (Sandbox Code Playgroud)

这是NSDatePicker菜单视图时的工作正常,但不适用于我的自定义视图.

我正在自定义视图中的文本字段中捕获回车键操作,但我能弄清楚的是如何取消菜单跟踪,这使得userAcceptedEdit == NO:

MyCustomViewController.mm:

- (IBAction)textFieldAction:(id)sender {
    logdbg(@"Action");
    NSMenu* menu = [[self.view enclosingMenuItem] menu];
    [menu cancelTracking];
}
Run Code Online (Sandbox Code Playgroud)

Apple的应用程序菜单和弹出列表编程主题的" 菜单项"部分中的视图不包含它...

编辑这是一个示例项目,它演示了这个问题.

有人可以提供一些指导吗?

tru*_*cks 2

您还应该能够将 textFields 的委托设置为 NSViewController,在 ViewController 中实现 NSTextFieldDelegate 并执行类似的操作

- (void)controlTextDidEndEditing:(NSNotification *)aNotification{
    // NSTextField * textField = [aNotification object];
    NSUInteger whyEnd = [[[aNotification userInfo] objectForKey:@"NSTextMovement"] unsignedIntValue];
    if(whyEnd == NSReturnTextMovement){
        // Create new event here using the below routine

        /*
        [[self window] keyDown: [NSEvent keyEventWithType:(NSEventType)type 
                                                 location:(NSPoint)location 
                                            modifierFlags:(NSUInteger)flags 
                                                timestamp:(NSTimeInterval)time 
                                             windowNumber:(NSInteger)windowNum 
                                                  context:(NSGraphicsContext *)context 
                                               characters:(NSString *)characters 
                              charactersIgnoringModifiers:(NSString *)unmodCharacters 
                                                isARepeat:(BOOL)repeatKey
                                                  keyCode:(unsigned short)code]
         ];
         */ 
    }
 }
Run Code Online (Sandbox Code Playgroud)

在这里,您实际上是通过创建一个新事件传递到父视图来将通知转换为事件

还应该注意的是,这成为所有文本字段的中央“调度”返回捕获器。

这是关于使用 NSEvent 创建方法的一个很好的链接: http://advinprog.blogspot.com/2008/06/so-you-want-to-post-keyboard-event-in.html

请注意这篇文章中如何模拟 key_down 和 key_up!