Cocoa 如何检测NSTextField中的双击
我有一个自定义的NSTextField,我想检测用户在文本字段中的双击。我的目标是:我希望能够双击表达式中的括号,例如“(2+2)=4”,并让它选择匹配括号内的所有内容。我想我可以用Cocoa 如何检测NSTextField中的双击,cocoa,nstextfield,double-click,Cocoa,Nstextfield,Double Click,我有一个自定义的NSTextField,我想检测用户在文本字段中的双击。我的目标是:我希望能够双击表达式中的括号,例如“(2+2)=4”,并让它选择匹配括号内的所有内容。我想我可以用 - (void)textView:(NSTextView *)textView doubleClickedOnCell:(id <NSTextAttachmentCell>)cell inRect:(NSRect)cellFrame atIndex:(NSUInteger)charIndex; -(v
- (void)textView:(NSTextView *)textView doubleClickedOnCell:(id <NSTextAttachmentCell>)cell inRect:(NSRect)cellFrame atIndex:(NSUInteger)charIndex;
-(void)textView:(NSTextView*)textView双击取消单元格:(NSRect)单元格框索引:(nsinteger)charIndex;
但它从未在我的自定义NSTextField中调用
然后我想我可以覆盖-mouseDown,但那也没有被调用。我被难住了。任何关于什么应该是易于实现的函数的建议
谢谢
Philip文本字段本身不处理编辑。当文本字段具有焦点时,将向窗口中添加一个文本视图,与文本字段区域重叠。这称为,它负责处理编辑 您最有可能更改双击行为的地方似乎是该文本视图使用的文本存储对象
NSTextStorage
继承自NSMutableAttributedString
,后者继承自NSAttributedString
,后者具有-双击索引:
方法。该方法返回双击特定索引时应选择的文本范围
因此,您需要实现NSTextStorage
的子类,该子类重写该方法并在某些情况下返回不同的结果NSTextStorage
是类集群的半抽象基类。子类化它需要比平常多一点。您必须实现NSAttributedString
和NSMutableAttributedString
的基本方法。看
有几个地方可以通过将字段编辑器的文本存储对象替换为类的实例来自定义字段编辑器:
- 您可以实现
的自定义子类。设置文本字段以将其用作单元格。在子类中,重写NSTextFieldCell
。在覆盖中,实例化一个-fieldEditorForView:
。获取其NSTextView
并调用layoutManager
,将自定义文本存储类的实例传递给它。(这比将涉及文本编辑的对象层次结构放在一起更容易,尽管您可以自己做。)将文本视图的-replaceTextStorage:
属性设置为true并返回它fieldEditor
- 在窗口代理中,实现
。如上所述,使用自定义文本存储创建、配置并返回-windowWillReturnFieldEditor:toObject:
李>NSTextView
NSTextStorage
——并不是正确的解决方案。在中,他们特别建议使用selectionRangeForProposedRange:granularity:
方法来平衡分隔符。根据Ken的回答,一旦启动了自定义字段编辑器,就应该使用NSTextView
的解决方案,应用于用于字段编辑器的自定义NSTextView
子类
如果有兴趣,使用
NSTextStorage
的doubleClickAtIndex:
方法进行分隔符平衡可能是错误的解决方案,原因很简单:(1)因为苹果这么说,(2)因为子类化NSTextStorage
复杂且容易出错,以及(3)因为NSTextView
提供了一种专门用于执行分隔符平衡等操作的方法。但这也是错误的,原因很简单:(4)doubleClickAtIndex:
被记录为“返回组成给定索引周围的单词(或其他语言单位)的字符范围,考虑到语言特征”。因此,doubleClickAtIndex:
实际上是关于文本的语言单位(即单词)是如何定义的,以某种方式重新定义这些语言单位以实现分隔符平衡可能会破坏单词级文本处理的其他方面。例如,我想如果您已经覆盖了doubleClickAtIndex:
来进行分隔符平衡,那么要使双击拖动(逐字拖出一个选择)正常工作是相当棘手的。Cocoa也可以使用doubleClickAtIndex:
来查找单词的其他方面,并且将来可能会增加它的更多用途。由于分隔符平衡的文本部分不是“单词”,谁知道会产生什么奇怪的结果呢。只需使用此类检测双击即可
final class doubleClickableTextField : NSTextField {
override func mouseDown(with event: NSEvent) {
super.mouseDown(with: event)
if (event.clickCount == 2){
// do the work here
self.isEditable = true
}
}
}
-textView:doubleClickedOnCell:inRect:atIndex:
在文本字段的委托上调用,而不是在自定义NSTextView上调用。文本字段是处理编辑的文本视图(字段编辑器)的委托。但无论如何,该方法仅适用于附件。我的textfield被调用用于textView:menu:forEvent:atIndex:和textView:shouldChangeTextInRange:replacementString:,但不用于DoubleClickedOncel:,因此Ken是正确的,文本字段是处理编辑的文本视图(字段编辑器)的代理。也许您可以在作为自定义字段编辑器提供的NSTextView
的子类中重写mouseDown:
。