Como con la redistribución del contenido de NSTextView para que mis caracteres de tabulación se dibujan con un ancho de 4 caracteres
-
21-09-2019 - |
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?
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.