1

当用户添加一个新的托管对象时,它会显示在一个表格中,该表格向下滚动到新条目,并且新对象的名称(默认值)进入编辑模式。

我需要检查新对象的名称在数据存储中是否唯一,因此我不能为此使用格式化程序。我认为我应该验证这一点的最佳时机是,每当用户尝试提交条目的名称值时,使用textShouldEndEditing:.

NSTableView对以下方法进行了子类化和覆盖,只是为了能够在它们被调用时检查日志。

- (BOOL)textShouldEndEditing:(NSText *)textObject {
    NSLog(@"textSHOULDendEditing fired in MyTableView");
    return [super textShouldEndEditing:textObject];
}
- (BOOL)control:(NSControl *)control textShouldEndEditing:(NSText *)fieldEditor {
    NSLog(@"control:textShouldEndEditing fired in MyTableView");
    return YES;
}
- (void)textDidEndEditing:(NSNotification *)aNotification {
    NSLog(@"textDIDEndEditing fired in MyTableView");
}

textDidEndEditing:被称为罚款,但textShouldEndEditing:没有。

NSTableView 类参考中,在 Text Delegate Methods 下,列出了两个方法textShouldEndEditing:和。textDidEndEditing:有人请解释为什么一个被调用而另一个没有。


我认为NSTableView充当代理行为NSTextField被实例化为. 所以在NSTableView 类参考中所说的委托方法,实际上是实现了对象的文本操作方法。NSTextFieldCellNSTextField

我试图NSTextFieldCell在我的NSTableView. 我还尝试在NSTableView.

#import <AppKit/AppKit.h>
#import <Cocoa/Cocoa.h>
@interface MyTableView : NSTableView <NSTextDelegate, NSTextFieldDelegate, NSControlTextEditingDelegate, NSTableViewDelegate, NSTableViewDataSource> {
}
@end

别笑,我什至尝试将我的表格视图声明为它自己的委托:P

4

3 回答 3

7

在这个问题上敲了一整天,却没有在 Apple 文档中找到任何确凿的答案后,我决定分享我找到的解决方案,以防其他人遇到同样的问题。

根据文档,正如原始海报所提到的,方法control:textShouldBeginEditingcontrol:textShouldEndEditingofNSControlTextEditingDelegate应该直接在委托上调用:

此消息由控件直接发送到其委托对象。

此外,Apple 还发布了一份技术问答,标题为检测 NSTableView 中单元格的开始和结束编辑会话,其中明确说明了以下内容:

A: 如何在 NSTableView 中检测单元格的开始和结束编辑会话?

为了检测用户何时开始和结束一个单元格的编辑会话NSTableView,您需要设置为该表的委托并实现以下NSControl委托方法:

- (BOOL)control:(NSControl *)control textShouldBeginEditing:(NSText *)fieldEditor;

- (BOOL)control:(NSControl *)control textShouldEndEditing:(NSText *)fieldEditor;

该表使用该方法将从文本视图获取的委托消息转发到您的委托对象control:textShouldEndEditing:。通过这种方式,您的委托可以获知文本视图字段编辑器代表其执行的控制。

我在 Apple 的文档中没有发现任何不同之处,如果有人这样做,文档指针将不胜感激。

事实上,如果使用的是基于单元的,这似乎是正确NSTableView的。但是,一旦您将表更改为基于视图的表,就不再在表委托对象上调用委托方法。

一个办法

但是,我执行的一些启发式测试表明,如果(并且据我所知:且仅当),这些委托方法会在基于视图的表委托上被调用:

  • 表委托已设置。
  • 可编辑控件的委托已设置。

如果您删除任一委托,NSControlTextEditingDelegate则不会调用协议的方法。

根据(唯一)文档,出乎意料的是设置可编辑控件的委托。另一方面,将委托对象设置为接收委托通知对我来说听起来很直观,这就是我首先尝试的原因。但是有一个问题!然而,奇怪的是,这不够。如果删除了表委托,NSControlTextEditingDelegate即使设置了可编辑控件的委托,也不会调用方法(这对我来说是最奇怪的事情)。

希望这可以帮助其他人不要在这个问题上浪费时间。

于 2014-06-16T11:30:05.873 回答
2

在您的问题中,您提到了“托管对象”的插入,这就是问题所在。似乎您正在使用基于视图的表格,但 textShouldEndEditing: 方法仅被基于单元格的表格调用。

于 2012-07-18T10:03:17.980 回答
1

-(void)awakeFromInsert;在(子类化的)托管对象中进行了覆盖,以构造名称属性的唯一默认值。

此外,我最终没有覆盖-(BOOL)textShouldEndEditing:表格视图中的方法。相反,我检查新输入的名称属性在(子类化)托管对象的-(BOOL)validate<Key>:error:.

总之,以上两种策略会在所有托管对象中产生唯一的名称属性。

也许我可以强制NSTextFieldCell进入编辑模式,导致-(BOOL)textShouldEndEditing:每次都被调用。


不过有一些评论:

-(BOOL)textShouldEndEditing:返回 NO 时似乎返回-(BOOL)validate<Key>:error:NO。

只有当用户实际更改属性时,才会调用-(BOOL)textShouldEndEditing:-(BOOL)validate<Key>:error:方法。

于 2012-04-16T15:17:34.890 回答