Wie NSScrollView von Scrollen nach oben zu stoppen, wenn horizontal NSTextView enthalten resizing?

StackOverflow https://stackoverflow.com/questions/1744945

Frage

Ich habe eine NSTextView, dass ich eine horizontale Bildlaufleiste angezeigt werden soll. Nach einigen Leitungen im Internet, habe ich die meisten davon arbeiten, außer, dass ich Probleme mit der vertikalen Bildlaufleiste habe.

Was ich getan habe ist, die Breite der längsten Zeile zu finden (in Pixeln mit dem angegebenen Schrift) und dann die Größe ich die NSTextContainer und die NSTextView angemessen. Auf diese Weise der horizontale Bildlaufleiste ist repräsentativ für die Breite und Scrollen nach rechts bis zum Ende der längsten Textzeile scrollt.

Nachdem diese Arbeit tat, bemerkte ich, dass mein NSScrollView zeigen würde, und die vertikale Bildlaufleiste ausgeblendet, wie ich getippt. Ich habe ‚fixed‘ dieses Problem, indem autohidesScrollers zu NO vor der Größe ändern und dann YES danach einstellen. Allerdings gibt es immer noch ein weiteres Problem, wo, wie ich geben, die vertikale Bildlaufleiste Daumen springt an die Spitze der Scrollbar und zurück an die richtige Stelle, wie ich geben. Ich tippe ‚a‘ , es nach oben springt, ich drücken Sie die wieder und springt sie wieder an die richtige Stelle.

Alle Gedanken?

Hier ist ein Beispielcode:

- (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];
        }
    }   
}
War es hilfreich?

Lösung

Dank Ross Carter Post auf die Cocoa-Dev Liste , ich dieses Problem behoben.

A. Sie müssen Ihre Textansicht einrichten horizontales Scrollen unterstützen:

- (void)awakeFromNib {
    [myTextView setHorizontallyResizable:YES];
    NSSize tcSize = [[myTextView textContainer] containerSize];
    tcSize.width = FLT_MAX;
    [[myTextView textContainer] setContainerSize:tcSize];
    [[myTextView textContainer] setWidthTracksTextView:NO];
}

B. Sie haben die Breite der Textansicht zu aktualisieren, da sie sich ändert, sonst wird die horizontale Scroll-Leiste nicht ordnungsgemäß aktualisiert werden:

- (void)textDidChange:(NSNotification *)notification
{
    [self updateTextViewWidth];
}

- (CGFloat)longestLineOfText
{
    CGFloat longestLineOfText = 0.0;

    NSLayoutManager* layoutManager = [myTextView layoutManager];

    NSRange lineRange;
    NSUInteger glyphIndex = 0;
    NSUInteger glyphCount = [layoutManager numberOfGlyphs];
    while (glyphIndex < glyphCount) {

        NSRect lineRect = [layoutManager lineFragmentUsedRectForGlyphAtIndex:glyphIndex
                                                              effectiveRange:&lineRange
                                                     withoutAdditionalLayout:YES];

        longestLineOfText = max(longestLineOfText, lineRect.size.width);

        glyphIndex = NSMaxRange(lineRange);
    }

    return longestLineOfText;

}

// ----------------------------------------------------------------------------

- (void)updateTextViewWidth
{
    static CGFloat previousLongestLineOfText = 0.0;

    CGFloat currentLongestLineOfText = [self longestLineOfText];
    if (currentLongestLineOfText != previousLongestLineOfText) {
        previousLongestLineOfText = currentLongestLineOfText;

        NSTextContainer* container = [myTextView textContainer];
        CGFloat padding = [container lineFragmentPadding];

        NSRect frame = [myTextView frame];
        frame.size.width = currentLongestLineOfText + padding * 2;
        [myTextView setFrame:frame];
    }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top