I have a NSTextView that I want to display a horizontal scroll bar. Following some leads on the internet, I have most of it working, except that I am having problems with the vertical scroll bar.
What I have done is to find the width of the longest line (in pixels with the given font) and then I resize the NSTextContainer and the NSTextView appropriately. This way the horizontal scroll bar is representative of the width and scrolling to the right will scroll to the end of the longest line of text.
After doing this work, I noticed that my NSScrollView would show and hide the vertical scroll bar as I typed. I've 'fixed' this problem by setting autohidesScrollers to NO before the resize and then YES afterwards. However, there still remains another problem where, as I type, the vertical scrollbar thumb jumps to the top of the scrollbar and back to the proper place as I type. I type 'a' <space>, it jumps to the top, I press the <space> again and it jumps back to the proper location.
Any thoughts?
Here is some sample code:
- (CGFloat)longestLineOfText
{
CGFloat longestLineOfText = 0.0;
NSRange lineRange;
NSString* theScriptText = [myTextView string];
NSDictionary* attributesDict = [NSDictionary dictionaryWithObject:scriptFont forKey:NSFontAttributeName]; //scriptFont is a instance variable
NSUInteger characterIndex = 0;
NSUInteger stringLength = [theScriptText length];
while (characterIndex < stringLength) {
lineRange = [theScriptText lineRangeForRange:NSMakeRange(characterIndex, 0)];
NSSize lineSize = [[theScriptText substringWithRange:lineRange] sizeWithAttributes:attributesDict];
longestLineOfText = max(longestLineOfText, lineSize.width);
characterIndex = NSMaxRange(lineRange);
}
return longestLineOfText;
}
// ----------------------------------------------------------------------------
- (void)updateMyTextViewWidth
{
static CGFloat previousLongestLineOfText = 0.0;
CGFloat currentLongestLineOfText = [self longestLineOfText];
if (currentLongestLineOfText != previousLongestLineOfText) {
BOOL shouldStopBlinkingScrollBar = (previousLongestLineOfText < currentLongestLineOfText);
previousLongestLineOfText = currentLongestLineOfText;
NSTextContainer* container = [myTextView textContainer];
NSScrollView* scrollView = [myTextView enclosingScrollView];
if (shouldStopBlinkingScrollBar) {
[scrollView setAutohidesScrollers:NO];
}
CGFloat padding = [container lineFragmentPadding];
NSSize size = [container containerSize];
size.width = currentLongestLineOfText + padding * 2;
[container setContainerSize:size];
NSRect frame = [myTextView frame];
frame.size.width = currentLongestLineOfText + padding * 2;
[myTextView setFrame:frame];
if (shouldStopBlinkingScrollBar) {
[scrollView setAutohidesScrollers:YES];
}
}
}