Como con la redistribución del contenido de NSTextView para que mis caracteres de tabulación se dibujan con un ancho de 4 caracteres

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

Pregunta

Estoy trabajando con un NSTextView y uno de los requisitos que tengo es que un carácter de tabulación, '\ t', tendrá el mismo ancho que cuatro espacios.

Así que el texto de contenido sería el siguiente:

AAAA
    AAAA - 1 tab
    AAAA - 4 spaces

Y así es como puedo lograr esto:

// done when NSTextView first loaded and when
// delegate's textDidBeginEditing gets called: (perhaps overkill, but is a work in progress).
- (void)updateMyTextViewTextAttributes
{
    NSMutableParagraphStyle* paragraphStyle = [[myTextView defaultParagraphStyle] mutableCopy];
    if (paragraphStyle == nil) {
        paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
    }
    float charWidth = [[myFont screenFontWithRenderingMode:NSFontDefaultRenderingMode] advancementForGlyph:(NSGlyph) ' '].width;
    [paragraphStyle setDefaultTabInterval:(charWidth * 4)];
    [paragraphStyle setTabStops:[NSArray array]];
    [myTextView setDefaultParagraphStyle:paragraphStyle];

    NSMutableDictionary* typingAttributes = [[myTextView typingAttributes] mutableCopy];
    [typingAttributes setObject:paragraphStyle forKey:NSParagraphStyleAttributeName];
    [typingAttributes setObject:scriptFont forKey:NSFontAttributeName];
    [myTextView setTypingAttributes:typingAttributes];
}

Esto permite que el diseño adecuado que se muestra con el texto inicial, así como mantener la tipificación atribuye la misma.

El problema es que el usuario final puede cambiar la fuente. Y cuando esto sucede, el texto de la muestra se desalinea. Al igual que el siguiente:

[smaller font]
AAAA
     AAAA - 1 tab
    AAAA - 4 spaces


[larger font]
AAAA
   AAAA - 1 tab
    AAAA - 4 spaces

He intentado llamar setNeedsDisplay de myTextView: SÍ como leí que termina llamando setNeedsDisplayInRect de NSTextView: avoidAdditionalLayout con un NO para el parámetro avoidAdditionalLayout. Esto no cambia nada.

He intentado llamar a mis updateMyTextViewTextAttributes llamar cuando myTextView tiene el nuevo conjunto myFont. Eso no cambia nada.

También he intentado contar la LayoutManager de myTextView a ensureLayoutForTextContainer para la textContainer de myTextView. Sin cambios.

En este punto, no estoy seguro de qué intentar después. ¿Alguna sugerencia?

¿Fue útil?

Solución

Douglas Davidson de Apple me proporcionó la pistas para llegar a la respuesta a través de la lista de correo electrónico cocoa-dev@apple.lists.com.

he resuelto el problema mediante la actualización de los updateMyTextViewTextAttributes funcionar de esta manera:

- (void)updateMyTextViewTextAttributes
{
   NSMutableParagraphStyle* paragraphStyle = [[myTextView defaultParagraphStyle] mutableCopy];

   if (paragraphStyle == nil) {
       paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
   }

   float charWidth = [[myFont screenFontWithRenderingMode:NSFontDefaultRenderingMode] advancementForGlyph:(NSGlyph) ' '].width;
   [paragraphStyle setDefaultTabInterval:(charWidth * 4)];
   [paragraphStyle setTabStops:[NSArray array]];

   [myTextView setDefaultParagraphStyle:paragraphStyle];

   NSMutableDictionary* typingAttributes = [[myTextView typingAttributes] mutableCopy];
   [typingAttributes setObject:paragraphStyle forKey:NSParagraphStyleAttributeName];
   [typingAttributes setObject:scriptFont forKey:NSFontAttributeName];
   [myTextView setTypingAttributes:typingAttributes];

   /** ADDED CODE BELOW **/
   NSRange rangeOfChange = NSMakeRange(0, [[myTextView string] length]);
   [myTextView shouldChangeTextInRange:rangeOfChange replacementString:nil];
   [[myTextView textStorage] setAttributes:typingAttributes range:rangeOfChange];
   [myTextView didChangeText];

   [paragraphStyle release];
   [typingAttributes release];
}

Otros consejos

¿Ha tratado de calcular el avance espacio con advancementForGlyph: directamente en la fuente en lugar de la fuente de pantalla?

float charWidth = [myFont advancementForGlyph:(NSGlyph) ' '].width;

Fuente de pantalla no está destinado a ser utilizado directamente fuera de la ventana del servidor:

  

Las fuentes de pantalla son para uso directo con   el servidor de ventanas solamente. Nunca los use   con objetos kit de aplicación, tales como   en setFont: métodos. Internamente, el   Kit de aplicación utiliza automáticamente el   fuente de pantalla correspondiente para una fuente   oponerse siempre que la vista no es   girado o reducido.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top