¿Cómo detener NSScrollView de desplazamiento hacia arriba cuando el cambio de tamaño horizontal contenida NSTextView?

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

Pregunta

Tengo un NSTextView que quiero mostrar una barra de desplazamiento horizontal. Después de algunos conductores en el Internet, tengo la mayor parte de trabajo, excepto que estoy teniendo problemas con la barra de desplazamiento vertical.

Lo que he hecho es encontrar el ancho de la línea más larga (en píxeles con la fuente dada) y luego cambiar el tamaño de la NSTextContainer y la NSTextView adecuadamente. De esta manera la barra de desplazamiento horizontal es representativa de la anchura y el desplazamiento a la derecha, se desplazará hasta el final de la línea más larga de texto.

Después de hacer este trabajo, me di cuenta de que mi NSScrollView sería mostrar y ocultar la barra de desplazamiento vertical mientras escribía. He 'fijo' este problema estableciendo autohidesScrollers a NO antes del cambio de tamaño y luego SÍ después. Sin embargo, todavía existe otro problema en que, mientras escribo, la barra de desplazamiento vertical pulgar salta a la parte superior de la barra de desplazamiento y de vuelta al lugar apropiado mientras se escribe. Me tipo 'A' , salta a la parte superior, pulsar el otra vez y salta de nuevo a la ubicación correcta.

¿Alguna idea?

Aquí hay algunos ejemplos de código:

- (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];
        }
    }   
}
¿Fue útil?

Solución

Gracias a Ross Carter puesto en el Cacao-Dev lista , que resuelve este problema.

A. Usted tiene que configurar su vista de texto para apoyar el desplazamiento horizontal:

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

B. Usted tiene que actualizar el ancho de la vista de texto a medida que cambia, de lo contrario la barra de desplazamiento horizontal no actualiza correctamente:

- (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];
    }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top