水平スクロールバーを表示したい NSTextView があります。インターネット上のいくつかのリードに従って、垂直スクロールバーに問題があることを除いて、ほとんどが機能しています。
私が行ったことは、最も長い行の幅 (指定されたフォントのピクセル単位) を見つけてから、NSTextContainer と NSTextView のサイズを適切に変更することです。このように、水平スクロール バーは幅を表し、右にスクロールするとテキストの最も長い行の終わりまでスクロールします。
この作業を行った後、入力したときに NSScrollView が垂直スクロール バーを表示および非表示にすることに気付きました。サイズ変更の前にautohidesScrollersをNOに設定し、その後YESに設定することで、この問題を「修正」しました。ただし、入力すると、垂直スクロールバーのつまみがスクロールバーの上部にジャンプし、入力すると適切な場所に戻るという別の問題が残っています。'a' <スペース> を入力すると、先頭にジャンプし、もう一度 <スペース> を押すと、適切な場所に戻ります。
何かご意見は?
サンプルコードは次のとおりです。
- (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];
}
}
}