Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Cocoa 如何检测NSTextField中的双击_Cocoa_Nstextfield_Double Click - Fatal编程技术网

Cocoa 如何检测NSTextField中的双击

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

我有一个自定义的NSTextField,我想检测用户在文本字段中的双击。我的目标是:我希望能够双击表达式中的括号,例如“(2+2)=4”,并让它选择匹配括号内的所有内容。我想我可以用

- (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:
    ,将自定义文本存储类的实例传递给它。(这比将涉及文本编辑的对象层次结构放在一起更容易,尽管您可以自己做。)将文本视图的
    fieldEditor
    属性设置为true并返回它
  • 在窗口代理中,实现
    -windowWillReturnFieldEditor:toObject:
    。如上所述,使用自定义文本存储创建、配置并返回
    NSTextView

根据苹果公司的说法,Ken Thomases在这里给出的答案是正确的,他分析了有关field editor以及如何替换它的问题,但随后提出的解决方案——替换field editor的
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: