I have a Cocoa, Document-based Mac OS X application.
One feature that I have in my app is a list of text items which can be double-clicked to edit. When the user double-clicks one of the text items, I place the current window's fieldEditor
text field over the clicked text item to allow editing.
Everything is working fine except for one problem. I cannot figure out how to make the fieldEditor
text field clip + scroll rather than wrap its text. Here's what it currently looks like:
See how the text is wrapping to a second line? I don't want that. I'd like it to remain one line which scrolls (and appears clipped).
Here's an example of it working correctly on a list item which has less text:
Here's what I'm trying in my view controller:
NSWindow *win = [listItemView window];
NSText *fieldEditor = [win fieldEditor:YES forObject:listItemView];
[fieldEditor setFont:[TDListItemView titleFont]];
[fieldEditor setAlignment:NSLeftTextAlignment];
[fieldEditor setDrawsBackground:YES];
[fieldEditor setBackgroundColor:[NSColor whiteColor]];
[fieldEditor setString:str];
[fieldEditor setDelegate:self];
[fieldEditor selectAll:nil];
if ([fieldEditor isKindOfClass:[NSTextView class]]) {
NSTextView *tv = (NSTextView *)fieldEditor;
NSMutableParagraphStyle *style = [[[tv defaultParagraphStyle] mutableCopy] autorelease];
[style setLineBreakMode:NSLineBreakByClipping];
[tv setDefaultParagraphStyle:style];
}
CGRect r = [self fieldEditorRectForBounds:[listItemView bounds] index:idx]; // height here is 10.0
[fieldEditor setFrame:r];
[fieldEditor setNeedsDisplay:YES];
[[self view] addSubview:fieldEditor];
[win makeFirstResponder:fieldEditor];
Notice that part in the middle: I check to see if this fieldEditor
is an instance of NSTextView
in order to call the setDefaultParagraphStyle:
method on it. This is my attempt to get the fieldEditor
to clip its text -- via the NSLineBreakByClipping
value. It's not having any effect. And I'm not even sure this is what I should be doing to get the fieldEditor
to scroll on one line.
Also note that the height of the rect which I compute in my -fieldEditorRectForBounds:index:
method is correct, and is providing a rect which is correctly sized for a single line of text (14.0 pixels in this case).
What am I missing to make the fieldEditor
display a single line of scrolled/clipped text?
I've also tried adding these lines in the middle section:
[[tv textContainer] setHeightTracksTextView:YES];
[[tv textContainer] setWidthTracksTextView:YES];
This has the desired effect of resizing the visible portion of the fieldEditor
which is good. But the bad news is that it doesn't change the fact that the text is still wrapped, rather than clipped + scrolled. :(
This seems related to this constant:
NSStringDrawingUsesLineFragmentOrigin
which can be used in the options:
argument of:
-[NSAttributedString drawWithRect:options:attributes:]
but in my case, I'm working from a NSText
field editor, not an NSAttributedString
. I can't figure out how to do this sort of thing with an NSText
field editor.
Hmmm ... NSTextView relies on an NSScrollView entirely for its scrolling behavior. I'm not sure if there's more to this that I'm not seeing, but it looks like the "historic" solution to your problem is either to:
Use A Different Control
You can use an editable NSTextField in its standard IB label configuration with editing enabled and scrolling selected as the behavior. It does all the heavy lifting for you already when configured properly - no need to mess around with the field editor directly.
...or to...
Cheat
Slap the field editor into an appropriately-sized and configured NSScrollView (allow only horizontal scroll; don't show the scrollers) dynamically, then remove the scroll view when finished editing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With