在Cocoa中解除模态对话框之前强制读取文本字段

时间:2009-04-06 11:48:26

标签: cocoa macos

在Mac OS X Cocoa应用程序中,我有一个应用程序模式对话框,其中包含绑定到共享用户默认值控制器的文本字段。如果我在编辑文本字段,然后在按下确定按钮之前将其标签远离它,那么一切都按预期工作。但是,如果我开始编辑一个字段,然后按Return键触发OK,该字段的旧值将保留在NSUserDefaults中。

那么,当编辑“不完整”时,如何强制更改的字段影响边界值?

从熟悉的文档中,我想我可以在解除对话之前为每个文本字段调用NSControl的validateEditing方法,但似乎应该有一个更简单的方法。

FWIW,这是显示对话框的代码:

- (void)showDialog {
    [NSApp activateIgnoringOtherApps:YES];
    [NSApp beginSheet:startTimerDialog
       modalForWindow:nil
        modalDelegate:nil
       didEndSelector:nil
          contextInfo:nil];
    [NSApp runModalForWindow:startTimerDialog];
    [NSApp endSheet:startTimerDialog];
    [startTimerDialog orderOut:self];
}

确定按钮(实际标题为“开始”)的目标是此方法:

- (IBAction)startTimerDialogStartButtonWasClicked:(id)sender {
    [self closeModalDialog:sender];

    // Then, call methods that read values from NSUserDefaults
    // ...    
}

4 个答案:

答案 0 :(得分:4)

向用户默认控制器发送commitEditing消息。

答案 1 :(得分:2)

这可能就是答案:

[startTimerDialog makeFirstResponder:nil];

根据文档,这会将resignFirstResponder发送到当前第一个响应者,这将导致编辑结束。

当然,第一响应者可以拒绝辞职,在这种情况下,makeFirstResponder将返回NO。所以我需要研究如何处理它。

答案 2 :(得分:1)

通过以下调用可以实现稍微突然的结束编辑方式:

[startTimerDialog endEditingFor:nil];

这总是有效的,但它比你大部分时间都需要的要强烈一些。 (有关“激烈”的更正式描述,请参阅下面的文档链接)

简而言之: -endEditingFor:只有当你无法让fieldEditor辞职第一响应者时才应该作为最后的手段。所以你可能想要在采取这样的极端措施之前尝试一种更微妙的方法。

为了更加微妙,在{{3>} for -EndEditingFor: Apple提出类似这样的内容:

if ( ![startTimerDialog makeFirstResponder:startTimerDialog] )
    /* Making the window firstResponder failed, proceed to
       force the first responder to resign */

    [startTimerDialog endEditingFor:nil];

按照上面的链接查看他们的确切示例代码,我在这里缩短了它,因为在你描述的用例中你显然对使用fieldEditor不感兴趣。

答案 3 :(得分:0)

您可以尝试为所有文本字段设置delegate并直接处理更改。