【问题标题】:NSTextView keyDown EventNSTextView keyDown 事件
【发布时间】:2013-03-21 11:11:18
【问题描述】:

我想用每个 Key 动作触发 keyDown 事件。因此我创建了一个 NSView 的子类。

@interface CodrTextView : NSView {
    NSTextField *lineNumberSpace;
    NSTextView *mainTextView;
}

- (id) initWithTextView:(NSTextView *)textView lineNumberSpace:(NSTextField *)textField;

我已经有了方法的:

- (id) initWithTextView:(NSTextView *)textView lineNumberSpace:(NSTextField *)textField {
   self = [self init];
   if (self){
       mainTextView = textView;
       lineNumberSpace = textField;
   }
   return self;
}

- (BOOL) acceptsFirstResponder {
   return YES;
}

- (BOOL)canBecomeKeyView {
   return  YES;
}

我的计划是计算 textView 中的行数并在 lineNumberSpace 中写入数字。我知道这些方法有效,因为我已经使用按钮上的 IBAction 对其进行了测试。方法是这样的:

- (long) getLineCount{
    NSString *content = [mainTextView string];
    NSUInteger numberOfLines, index, contentLength = [content length];
    for (index = 0, numberOfLines = 0; index < contentLength; numberOfLines++){
         index = NSMaxRange([content lineRangeForRange:NSMakeRange(index, 0)]);
    }

    NSLayoutManager *layoutManager = [mainTextView layoutManager];
    NSUInteger numberOfGlyphs =[layoutManager numberOfGlyphs];
    NSRange lineRange;
    for (numberOfLines = 0, index = 0; index < numberOfGlyphs; numberOfLines++){
         (void) [layoutManager lineFragmentRectForGlyphAtIndex:index
                                           effectiveRange:&lineRange];
          index = NSMaxRange(lineRange);
    }
    numberOfLines++;
    return numberOfLines;
}

- (void)keyDown:(NSEvent *)event {
     NSMutableString *lineNumberString = [NSMutableString string];
     long numberOfLines = [self getLineCount];

     for (int i = 1; i <= numberOfLines; i++){
         [lineNumberString appendString:([NSString stringWithFormat:@"%d \n", i])];
     }
     [lineNumberSpace setStringValue:lineNumberString];
}

这种方法确实有效。问题是,使用按钮,lineNumberSpace 中的数字正在正确更改,但使用 keyDown 事件它不起作用。我的错误是什么?

【问题讨论】:

  • 如果你在 "keyDown:" 方法中设置断点,在 Xcode 中执行 "setStringValue:" 的行是否命中?
  • 这就是问题所在,我认为 keyDown 事件有问题。
  • 试试这个:如果你在“keyDown:”方法的开始设置断点(例如,创建可变字符串的代码行),那个当你按下按键的时候?
  • 不,它也不要破坏。

标签: events nstextfield keydown nstextview first-responder


【解决方案1】:

啊,看看你的代码,我现在意识到问题所在了。

您的“CodrTextView”对象不是“NSTextView”的子类(而且,当您以编程方式或通过 XIB 或 Storyboard 实例化对象时,请确保文本视图对象是“@987654323”的自定义类@" 而不仅仅是另一个 "NSTextView"),所以它实际上也没有得到 "acceptsFirstResponder" 或 "canBecomeKeyView" 方法调用。

您需要从“NSTextView”而不是“NSView”下降“CodrTextView”,或者您需要创建另一个子类“NSTextView”对象将接收“keyDown:”事件,然后调用代码计算进入主视图“lineNumberSpace”的字符串。

这对你现在有意义吗?

【讨论】:

  • 是的,这对我来说很有意义。我将 CodrTextView 中的扩展类从“NSView”更改为“NSTextView”。但它已经不中断 keyDown 事件。你是什​​么意思:“确保文本视图对象是“CodrTextView”的自定义类,而不仅仅是另一个“NSTextView””?我该怎么做?
  • 当您在文本视图中键入时,它是“NSTextView”对象还是您的“CodrTextView”对象?该文本视图对象是如何创建的?
  • 我将 "NSScrollView" 和 "NSTextView" 从对象库中放入 .xib 文件中。我虽然 "CodrTextView" 是在控制器对象中创建的:"mainTextView = [[CodrTextView alloc] initWithTextView:scriptView lineNumberSpace:lineNumbers];"
  • 我会这样解决这个问题:你需要去掉“NSScrollView”。将“NSTextView”拖放到您的 xib 文件中。将其自定义类型更改为“CodrTextView”。 这将允许您接收“keyDown:”事件。然后,您需要弄清楚如何连接“lineNumberSpace”文本字段,因为您的“CodrTextView”需要从 XIB 文件中实例化,而不是通过“initWithTextView:”创建。
  • 好的,非常感谢您的帮助。我会试试。我看到的唯一问题是我需要滚动文本视图。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-10-18
  • 2016-03-18
  • 2014-06-12
  • 2019-05-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多