2

I want trigger the keyDown Event with every Key action. Therefore I have created a subclass of NSView.

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

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

I already have the method's:

- (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;
}

My plan is to count the lines in the textView and write the numbers in the lineNumberSpace. I know that the methods work, because I have test it already with an IBAction on a button. This is the method:

- (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];
}

This method works surely. The problem is, with a button the number in the lineNumberSpace is changing correctly but with the keyDown Event it don't work. What is my mistake here?

Chryb
  • 547
  • 1
  • 12
  • 34

1 Answers1

1

Ahhh, looking at your code I now realize what the problem is.

Your "CodrTextView" object is not subclassed from "NSTextView" (and also, when you instantiate the object programatically or via your XIB or Storyboard, make sure the text view object is a custom class of "CodrTextView" and not just another "NSTextView"), so it's not actually getting the "acceptsFirstResponder" or "canBecomeKeyView" method calls either.

You need to descend "CodrTextView" from "NSTextView" instead of "NSView", OR you need to create another subclassed "NSTextView" object which will receive the "keyDown:" event and then it'll call the code that calculates the string that goes into "lineNumberSpace" of your main view.

Does this make sense to you now?

Michael Dautermann
  • 88,797
  • 17
  • 166
  • 215
  • Yes it makes sense for me. I changed the extended class in CodrTextView to "NSTextView" from "NSView". But it already don't break in the keyDown Event. What do you mean with: "make sure the text view object is a custom class of "CodrTextView" and not just another "NSTextView""? How can i do this? – Chryb Mar 21 '13 at 11:47
  • When you are typing into the text view, is it a "`NSTextView`" object or is it your "`CodrTextView`" object? How is that text view object created? – Michael Dautermann Mar 21 '13 at 11:51
  • I put a `"NSScrollView"` with a `"NSTextView"` inside from the Object Library into the .xib File. I though the `"CodrTextView"` is created in the controller object with: `"mainTextView = [[CodrTextView alloc] initWithTextView:scriptView lineNumberSpace:lineNumbers];"` – Chryb Mar 21 '13 at 11:54
  • Here's how I would fix this: you need to get rid of the "`NSScrollView`". Drop a "`NSTextView`" into your xib file. Change it's custom type to "`CodrTextView`". ***This*** will allow you to receive "`keyDown:`" events. You then need to figure out how to connect up the "`lineNumberSpace`" text field, because your "`CodrTextView`" needs to be instantiated from the XIB file and not created via "`initWithTextView:`". – Michael Dautermann Mar 21 '13 at 12:11
  • Ok, tons of thanks for the help. I will try it. The only problem i see is that I need to scroll the textview. – Chryb Mar 21 '13 at 12:24
  • When you create a textview via Xcode's Interface Builder, a scrollview is put in automatically for you. – Michael Dautermann Mar 21 '13 at 12:36
  • Mhh, now it works with the breakpoints in the keyDown Method, but i can't write anything in the textview. And i can change the textview to an CodrTextView, but i can't get the TextView out of the Scroll View and there is no object with a NSTextView only. – Chryb Mar 21 '13 at 13:52
  • Ok thats strange, if i delete the keyDown Event method and i write with normal letters in the TextView this come out: |||||||||| – Chryb Mar 21 '13 at 13:56
  • Sorry, I'am really new in xCode programming. – Chryb Mar 21 '13 at 15:48