当用户添加新的托管对象时,它会显示在一个表格中,该表格向下滚动到新条目,新对象的名称(默认值)将进入编辑模式。
我需要检查数据存储区中新对象的名称是否唯一,因此我不能使用格式化程序。我认为,只要用户尝试使用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 Class Reference中,在文本委派方法下,列出了textShouldEndEditing:
和textDidEndEditing:
两种方法。有人请解释为什么一个人被召唤而另一个没有。
我认为NSTableView
充当NSTextField
的委托,该NSTextFieldCell
被实例化为NSTextField
的黑匣子委托。因此NSTableView Class Reference中所谓的委托方法实际上实现了NSTextFieldCell
对象的文本操作方法。
我尝试将NSTableView
声明为NSTableView
中的插座。我还试图在#import <AppKit/AppKit.h>
#import <Cocoa/Cocoa.h>
@interface MyTableView : NSTableView <NSTextDelegate, NSTextFieldDelegate, NSControlTextEditingDelegate, NSTableViewDelegate, NSTableViewDataSource> {
}
@end
。
{{1}}
不要笑,我甚至试图将我的表视图声明为自己的委托:P
答案 0 :(得分:6)
在没有在Apple文档中找到任何确凿答案的情况下,在这个问题上敲了一整天之后,我决定分享我找到的解决方案,以防其他人在遇到同样的问题。
根据文档,正如原始海报所提到的,control:textShouldBeginEditing
的{{1}}和control:textShouldEndEditing
方法应该在代理上直接 :
此消息由控件直接发送到其委托对象。
此外,技术问答由Apple发布,标题为Detecting the start and end edit sessions of a cell in NSTableView,其中明确说明如下:
答:如何在NSTableView中检测单元格的开始和结束编辑会话?
为了检测用户何时开始和结束
NSControlTextEditingDelegate
中单元格的编辑会话,您需要设置为该表的委托并实现以下NSTableView
委托方法:
NSControl
- (BOOL)control:(NSControl *)control textShouldBeginEditing:(NSText *)fieldEditor;
该表使用
- (BOOL)control:(NSControl *)control textShouldEndEditing:(NSText *)fieldEditor;
方法将从文本视图获取的委托消息转发到您的委托对象。这样,您的代理可以被告知文本视图字段编辑器代表它执行哪个控件。
我在Apple的文档中发现没有表明任何不同的内容,如果有人这样做,那么文档指针真的很受欢迎。
实际上,如果正在使用基于单元格的control:textShouldEndEditing:
,这似乎是 true 。但是,只要将表更改为基于视图的表,委托方法就会在表委托对象上不再被调用。
但是,我执行的一些启发式测试表明,如果(并且据我所知:并且仅在以下情况下),在基于视图的表委托上调用这些委托方法:
如果删除任一委托,则不会调用NSTableView
协议的方法。
根据the (only) documentation的意外情况是设置可编辑控件的委托。另一方面,将委托对象设置为接收委托通知听起来相当直观给我,这就是我首先尝试的原因。但有一个问题!然而,奇怪的是,不就足够了。如果删除了表委托,即使设置了可编辑控件的委托,也不会调用NSControlTextEditingDelegate
方法(对我来说这是最奇怪的事情)。
希望这有助于其他人不要在这个问题上浪费时间。
答案 1 :(得分:1)
在您的问题中,您提到插入“托管对象”,这就是问题所在。您似乎正在使用基于视图的表,但仅为基于单元格的表调用textShouldEndEditing:方法。
答案 2 :(得分:0)
我在(子类)托管对象中覆盖-(void)awakeFromInsert;
,为name-property构造一个唯一的默认值。
另外,我最终没有覆盖表视图中的-(BOOL)textShouldEndEditing:
方法。相反,我检查(子类)托管对象的-(BOOL)validate<Key>:error:
中新输入的名称属性是否唯一。
总之,上述两种策略会在所有托管对象中产生唯一的名称属性。
也许我可以迫使NSTextFieldCell
进入编辑模式,每次都会调用-(BOOL)textShouldEndEditing:
。
但有些评论:
当-(BOOL)textShouldEndEditing:
返回NO时,似乎-(BOOL)validate<Key>:error:
返回NO。
仅当用户实际对属性进行更改时,-(BOOL)textShouldEndEditing:
和-(BOOL)validate<Key>:error:
方法才会被称为。