Re: RegEx in cocoa, and where to dl PB+IB?
Re: RegEx in cocoa, and where to dl PB+IB?
- Subject: Re: RegEx in cocoa, and where to dl PB+IB?
- From: Douglas Davidson <email@hidden>
- Date: Mon, 29 Apr 2002 10:53:35 -0700
On Saturday, April 27, 2002, at 10:20 PM, Cryx wrote:
I'm sending this back to the list because I'm interesting in whether
anyone else has an elegant solution to the "vertical scrolling text
field that can easily process a raw keyDown".
Well, first of all, Cocoa views do not themselves handle scrolling.
When views scroll, they do so because they are subviews of an
NSScrollView, which is what handles the scrolling. It's a little more
complicated than that; see the NSScrollView documentation for more
info. Any Cocoa view can be made to scroll by being wrapped in a scroll
view, and there is a menu item in IB that will accomplish this.
Second, text fields don't actually handle text entry. That may sound a
little odd, but here's how it works: an NSTextField is a control, and
usually (like other controls) it uses an NSCell to display its
contents. However, when it becomes first responder and needs more
sophisticated text handling--either for selection or for input--it asks
its window for an NSTextView, called the "field editor", to stand in for
it and handle selection and input. There is usually one such field
editor for each window, shared by all of the controls in the window that
need it.
Third, in most cases you don't actually want *raw* keyDown:'s. That's
because keyDown: takes place before all of the key binding and input
management that is necessary in general to make sense of keystrokes.
Also, to get keyDown: you will need to subclass NSTextView. In most
cases you can get what you want without subclassing at all, just by
acting as the delegate of an NSTextView or an NSTextField. See below
for more information on key event flow.
Probably the easiest thing to do here is just to use an NSTextView from
the beginning. NSTextView has a number of options that NSTextField
lacks, and you can get one conveniently wrapped in a scroll view off of
IB's palette. You can choose to have your NSTextView act like a field
editor (i.e., like a text field) as far as returns and tabs goes just by
sending it setFieldEditor:YES; then returns and tabs will end editing
rather than inserting returns or tabs.
If you want to use an NSTextField, you can still do so, and you may be
able to do what you want as its delegate. If not, you can get your
window to give it a custom field editor; however, you don't get to be
the field editor's delegate, because the NSTextField wants to do that.
The other option with NSTextField is to use a custom NSFormatter, which
is often a much simpler way of controlling what the user can input into
a text field. You should definitely use an NSFormatter if it can do
what you want to do.
Here's what I wrote last time the subject of key events in text came up:
"Here is the normal sequence when a text view receives key events:
NSTextView's keyDown: passes events to interpretKeyEvents:, which is
where they enter key binding and input management. They come out either
as insertText: or as doCommandBySelector: (see NSResponder.h for these
three methods).
In particular, an enter or return will (with the standard key bindings)
end up using doCommandBySelector: to call insertNewline: on the
NSTextView. If the textview is not a field editor, this will call
insertText: to insert a newline character. If it is a field editor (for
example, when editing a textfield) this will end editing instead. An
arbitrary text view can be made to act in either of these ways by
calling setFieldEditor:.
A tab or backtab will (with the standard key bindings) end up using
doCommandBySelector: to call insertTab: or insertBacktab: on the
NSTextView. If the textview is not a field editor, insertTab: will call
insertText: to insert a tab character; insertBacktab: will do nothing.
If it is a field editor, this will end editing instead.
If you want to do something special when e.g. a tab key is pressed, you
should be able to implement the text view delegate method
- (BOOL)textView:(NSTextView *)aTextView
doCommandBySelector:(SEL)aSelector;
and check whether aSelector == @selector(insertTab:), and at that point
do something other than the default.
If you want to handle some key that actually inserts text, you can
implement
- (BOOL)textView:(NSTextView *)textView
shouldChangeTextInRange:(NSRange)affectedCharRange
replacementString:(NSString *)replacementString;
which will allow you to veto or modify any user-initiated change of the
text. You can do the same for changes of selection with
- (NSRange)textView:(NSTextView *)textView
willChangeSelectionFromCharacterRange:(NSRange)oldSelectedCharRange
toCharacterRange:(NSRange)newSelectedCharRange;
Now, if you are dealing with a textfield rather than a textview, then
you will automatically get a shared textview configured as a field
editor when your textfield has focus. The easiest thing then would
probably be to implement the control delegate method
- (BOOL)control:(NSControl *)control textView:(NSTextView *)textView
doCommandBySelector:(SEL)commandSelector;
in your textfield's delegate, and do something similar.
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.