NSTextView keyDown Question

  • Hi,

    This is a relatively simple question i think, but basically i have an
    NSTextView and I want to be able to check out the keys that the user
    presses when they type. If the key is not a 'special key' (defined in
    the program - for example: "(" or "/" or return), then i want that
    key to get passed on to the NSTextView like normal.

    I have tried subclassing NSTextView and over-riding the keyDown
    method, but when i do that, nothing gets passed on to the textView.

    I then tried keyUp which is good, except that it doesnt fire on
    repeated keystrokes, say if the user holds down a key.

    Is there some method i can call to just pass on the text/action to
    the TextField if the key is of no interest to the application?

    (I tried using insertText, but that doesnt work for delete and arrow
    keys, etc)

    Cheers

    - Nik
  • On 20 dec 2005, at 11.30, Nik Youdale wrote:

    > This is a relatively simple question i think, but basically i have
    > an NSTextView and I want to be able to check out the keys that the
    > user presses when they type. If the key is not a 'special
    > key' (defined in the program - for example: "(" or "/" or return),
    > then i want that key to get passed on to the NSTextView like normal.
    >
    > I have tried subclassing NSTextView and over-riding the keyDown
    > method, but when i do that, nothing gets passed on to the textView.
    >
    > I then tried keyUp which is good, except that it doesnt fire on
    > repeated keystrokes, say if the user holds down a key.
    >
    > Is there some method i can call to just pass on the text/action to
    > the TextField if the key is of no interest to the application?
    >
    > (I tried using insertText, but that doesnt work for delete and
    > arrow keys, etc)

    Have you tried using the
    "textView:shouldChangeTextInRange:replacementString:" delegate method?

    j o a r
  • No, I havnt tried that. I don't think its quite what I'm looking for.
    Maybe I should explain it in a bit more detail.

    The whole scenario is a bit complicated, but basically i have created
    a custom view that contains an NSTextView, which is what the user
    types in to. Now, I want the user to be able to type into this field
    and edit it as normal, except when certain characters are pressed,
    like "(" I want to be able to call a class method, and stop that
    keystroke from entering into the textView.

    So basically it is just a checking mechanism and also a blocking
    system for certain characters, and a way to call methods via certain
    keystrokes if you know what i mean.

    - Nik
    On 20/12/2005, at 9:37 PM, j o a r wrote:

    >
    > On 20 dec 2005, at 11.30, Nik Youdale wrote:
    >
    >> This is a relatively simple question i think, but basically i have
    >> an NSTextView and I want to be able to check out the keys that the
    >> user presses when they type. If the key is not a 'special
    >> key' (defined in the program - for example: "(" or "/" or return),
    >> then i want that key to get passed on to the NSTextView like normal.
    >>
    >> I have tried subclassing NSTextView and over-riding the keyDown
    >> method, but when i do that, nothing gets passed on to the textView.
    >>
    >> I then tried keyUp which is good, except that it doesnt fire on
    >> repeated keystrokes, say if the user holds down a key.
    >>
    >> Is there some method i can call to just pass on the text/action to
    >> the TextField if the key is of no interest to the application?
    >>
    >> (I tried using insertText, but that doesnt work for delete and
    >> arrow keys, etc)
    >
    > Have you tried using the
    > "textView:shouldChangeTextInRange:replacementString:" delegate method?
    >
    > j o a r
    >
    >
  • Hi Nik,

    I think what Joar is suggesting is exactly what you need. Perhaps you
    can even set your text view subclass as its own delegate. When that
    delegate method is called, return NO to prevent the special
    characters from entering the text view while doing whatever you want
    with them. Although the keystroke will enter the text handling
    system, I do not think it enters the view (someone correct me if I'm
    wrong on this).

    -Phil

    On Dec 20, 2005, at 12:43 PM, Nik Youdale wrote:

    > No, I havnt tried that. I don't think its quite what I'm looking
    > for. Maybe I should explain it in a bit more detail.
    >
    > The whole scenario is a bit complicated, but basically i have
    > created a custom view that contains an NSTextView, which is what
    > the user types in to. Now, I want the user to be able to type into
    > this field and edit it as normal, except when certain characters
    > are pressed, like "(" I want to be able to call a class method, and
    > stop that keystroke from entering into the textView.
    >
    > So basically it is just a checking mechanism and also a blocking
    > system for certain characters, and a way to call methods via
    > certain keystrokes if you know what i mean.
    >
    > - Nik
    > On 20/12/2005, at 9:37 PM, j o a r wrote:
    >
    >>
    >> On 20 dec 2005, at 11.30, Nik Youdale wrote:
    >>
    >>> This is a relatively simple question i think, but basically i
    >>> have an NSTextView and I want to be able to check out the keys
    >>> that the user presses when they type. If the key is not a
    >>> 'special key' (defined in the program - for example: "(" or "/"
    >>> or return), then i want that key to get passed on to the
    >>> NSTextView like normal.
    >>>
    >>> I have tried subclassing NSTextView and over-riding the keyDown
    >>> method, but when i do that, nothing gets passed on to the textView.
    >>>
    >>> I then tried keyUp which is good, except that it doesnt fire on
    >>> repeated keystrokes, say if the user holds down a key.
    >>>
    >>> Is there some method i can call to just pass on the text/action
    >>> to the TextField if the key is of no interest to the application?
    >>>
    >>> (I tried using insertText, but that doesnt work for delete and
    >>> arrow keys, etc)
    >>
    >> Have you tried using the
    >> "textView:shouldChangeTextInRange:replacementString:" delegate
    >> method?
    >>
    >> j o a r
    >>
    >>
    >
    > _______________________________________________
    > Do not post admin requests to the list. They will be ignored.
    > Cocoa-dev mailing list      (<Cocoa-dev...>)
    > Help/Unsubscribe/Update your Subscription:
    > http://lists.apple.com/mailman/options/cocoa-dev/<dev...>
    >
    > This email sent to <dev...>
    >
  • On 20 dec 2005, at 13.12, Philip Dow wrote:

    > Perhaps you can even set your text view subclass as its own delegate.

    Note that this is most often not possible, as many classes have
    checks to prevent objects from being their own delegate.

    Also, if you decide to use delegate methods, ask yourself if you
    really need a text view subclass at all?

    This is at the heart of good Cocoa design: Keep the core Cocoa
    classes as they are, and collect your business logic in controller
    and delegate classes.

    j o a r
  • On Dec 20, 2005, at 2:30 AM, Nik Youdale wrote:

    > This is a relatively simple question i think, but basically i have
    > an NSTextView and I want to be able to check out the keys that the
    > user presses when they type. If the key is not a 'special
    > key' (defined in the program - for example: "(" or "/" or return),
    > then i want that key to get passed on to the NSTextView like normal.
    >
    > I have tried subclassing NSTextView and over-riding the keyDown
    > method, but when i do that, nothing gets passed on to the textView.
    >

    Let me review again the path that keystrokes take in the text
    system.  First, generally speaking you do not want to override -
    [NSTextView keyDown:] in most cases; keyDown: is the entry point for
    raw keystrokes before they have been interpreted by input methods or
    anything else, and if you are not careful in modifying it you can
    easily break e.g. Japanese input.

    NSTextView takes keystrokes as they come in to keyDown: and passes
    them to the key binding system, from which they come back to the text
    view either as insertText: (for ordinary keys) or as
    doCommandBySelector: (for keys bound to various commands, such as
    arrow keys, return, tab, etc.).  At this point you can intervene,
    either in a subclass, or with the delegate's
    textView:doCommandBySelector:.  Bear in mind that insertText: can
    receive either an NSString (in the usual case) or an
    NSAttributedString (for some input methods).

    The delegate will also receive
    textView:shouldChangeTextInRanges:replacementStrings: when the user
    alters the text in any way--by ordinary keystrokes, by special
    keystrokes that modify the text (e.g. return), by menu commands, by
    pasting, by drag and drop, etc.  This is the point to intervene if
    you are not concerned about typing specifically, but about all user
    modifications to the text.

    In addition, there are other delegate methods such as
    textView:willChangeSelectionFromCharacterRanges:toCharacterRanges:
    and textView:shouldChangeTypingAttributes:toAttributes: that deal
    with other consequences of user actions, such as changes in selection
    or changes in the attributes that will be applied to subsequently
    typed text.  For example, arrow keys will modify the selection but
    not the text; likewise, picking "bold" from a menu when there is no
    text selected will modify the typing attributes but not the text.

    Douglas Davidson