La fuente instalada personalizada no se muestra correctamente en UILabel


83

Estoy intentando utilizar una fuente Helvetica Neue Condensed que obtuve del paquete Adobe Font Collection Pro. Desafortunadamente, parece dibujarse incorrectamente cuando lo uso dentro de un UILabel.

La altura de la línea parece calculada correctamente (creo), pero cuando se muestra la fuente, se alinea con la parte superior del cuadro delimitador. Llamé [myLabel sizeToFit]y solo ajusté el ancho para producir esta captura de pantalla:

Captura de pantalla de representación incorrecta de fuentes

Tuve el mismo problema con la versión regular y en negrita de la fuente. Pude sacar una versión de Helvetica Neue Bold de OSX y ponerla en mi dispositivo y se ve bien (fondo verde en la imagen de arriba).

¿Qué podría estar mal con el archivo de fuente o con mi código que haría que se dibujara de esta manera?


¿Podría de alguna manera hacer una subclase de UIFont que pueda solucionar estos problemas?
MikeQ

+1 - el mismo problema para mí. Intenté usar ZFont para ayudar con esto, y ayuda un poco, pero no lo suficiente. Puede que haya algo mal en la forma en que se interpreta el encabezado con esas fuentes personalizadas (no tengo ni idea, en realidad, ¡pero tengo que pensar que puede tener algo que ver con eso!).
Joe D'Andrea

¡Hola! ¿Encontraste finalmente la solución? Por favor responda su pregunta si la respuesta es afirmativa. Gracias por adelantado.
Soonts

Desafortunadamente, no, no lo hice. Y ya no tengo acceso al archivo de fuente original que causó este problema. Me gusta la respuesta de kolyuchiy .. Solo desearía poder probarlo en mi caso específico.
MikeQ

Para que lo sepas, esto se ha solucionado en iOS7.
The dude

Respuestas:


125

Publiqué una solución que implica parchear el archivo de fuente ttf aquí :

Aquí está la solución que funcionó para mi fuente personalizada que tenía el mismo problema en UILabel, UIButton y demás. El problema con la fuente resultó ser el hecho de que su propiedad ascendente era demasiado pequeña en comparación con el valor de las fuentes del sistema. Ascender es un espacio en blanco vertical sobre los caracteres de la fuente. Para arreglar su fuente, tendrá que descargar las utilidades de línea de comandos de Apple Font Tool Suite . Luego tome su fuente y haga lo siguiente:

~$ ftxdumperfuser -t hhea -A d Bold.ttf

Esto creará Bold.hhea.xml. Ábralo con un editor de texto y aumente el valor del ascenderatributo. Tendrá que experimentar un poco para encontrar el valor exacto que mejor funcione para usted. En mi caso, lo cambié de 750 a 1200. Luego, ejecute la utilidad nuevamente con la siguiente línea de comando para fusionar sus cambios nuevamente en el archivo ttf:

~$ ftxdumperfuser -t hhea -A f Bold.ttf

Luego, use la fuente ttf resultante en su aplicación.


¡Muchas gracias por sugerir esta herramienta! también se puede usar para cambiar el nombre de una fuente editando la sección "-t name" de la misma manera.
Philippe

1
También puede intentar Mensis o FontForge. Estas aplicaciones también se pueden usar para cambiar la propiedad del ascendedor.
kolyuchiy

1
Me has alegrado el día. Estuve atrapado con este problema desde hace varias semanas. ¡Puedo usarlo con bastante frecuencia!
TheBeardedCoda

1
Tenga en cuenta que, al aumentar el ascendente, aumentará el espacio entre líneas; este puede ser el problema si tiene texto de varias líneas en su aplicación.
Pavel Alexeev

2
** POR FAVOR, VEA TAMBIÉN LA RESPUESTA DE JOSEPH LIN A CONTINUACIÓN ** ¡Debe ajustar tanto el ascendedor como el espacio entre líneas en cero para asegurar una buena alineación tanto en iOS 6 como en iOS 7!
Ken M. Haggerty

64

Entonces esta es una versión modificada de la respuesta de kolyuchiy .

Abrí mi fuente con Glyphs y luego la exporté sin modificar nada. De alguna manera, mágicamente, ¡el problema de la alineación vertical desapareció!

Lo que es mejor es que la nueva fuente funciona bien con métodos como sizeWithFont:, por lo que no tiene los problemas mencionados por Joshua .

Eché un vistazo a la tabla HHEA con el comando que mencionó kolyuchiy, y noté que Glyphs modificaba no solo el ascender, sino también lineGapy numberOfHMetricspara mí.

Aquí están los datos sin procesar, antes:

versionMajor="1"
versionMinor="0"
ascender="780"
descender="-220"
lineGap="200"
advanceWidthMax="1371"
minLeftSideBearing="-73"
minRightSideBearing="-52"
xMaxExtent="1343"
caretSlopeRise="1"
caretSlopeRun="0"
caretOffset="0"
metricDataFormat="0"
numberOfHMetrics="751"

y después:

versionMajor="1"
versionMinor="0"
ascender="980"
descender="-220"
lineGap="0"
advanceWidthMax="1371"
minLeftSideBearing="-73"
minRightSideBearing="-52"
xMaxExtent="1343"
caretSlopeRise="1"
caretSlopeRun="0"
caretOffset="0"
metricDataFormat="0"
numberOfHMetrics="748"

Entonces, la moraleja de la historia: no solo aumenta el ascendente, sino que también modifica otros valores relacionados.

No soy un experto en tipografía, así que no puedo explicar el por qué ni el cómo. Si alguien puede proporcionar una mejor explicación, ¡sería muy apreciado! :)


Después de haber guardado el TTF que estoy usando de nuevo con Glyphs, la fuente se comporta prácticamente igual en iOS 6 y iOS 7. Anteriormente, su línea de base estaba desalineada en iOS 6.
leolobato

6
¡Gracias por finalmente resolver esto! Aparentemente, iOS 6 respeta la propiedad lineGap, mientras que iOS 7 la ignora. La solución es hacer que lineGap sea 0 y hacer que el ascendente sea correspondientemente más grande. Esto es exactamente lo que hizo Glyphs, y funciona tanto en iOS 6 como en iOS 7.
phatmann

Si. Reducir el lineGap a cero (0) y dejar el ascendente (en 1991) me resolvió el problema con la fuente gratuita "Overpass" de Fedora. Gracias a todos por la orientación hacia una solución. Funciona tanto en iOS6 como en iOS7.
stephenhouser

Llegué a la misma conclusión que la de @ phatmann después de varios intentos fallidos con Glyphs y OS X Font Tools. La cuestión es que es mejor usar este truco con OS X Font Tools en lugar de simplemente exportar con Glyphs, porque Glyphs también edita el nombre del estilo de la fuente y el nombre de la posdata, lo que hace que xCode no encuentre la fuente en algunas situaciones.
huong

32

iOS 6 respeta la propiedad lineGap de la fuente, mientras que iOS 7 la ignora. Por lo tanto, solo las fuentes personalizadas con un espacio de línea de 0 funcionarán correctamente en ambos sistemas operativos.

La solución es hacer que lineGap sea 0 y hacer que el ascendente sea correspondientemente más grande. Según la respuesta anterior, una solución es importar y exportar desde Glyphs. Sin embargo, tenga en cuenta que una versión futura de la aplicación podría solucionar este "error".

Una solución más sólida es editar la fuente usted mismo, según esta publicación . Específicamente,

  1. Instale las herramientas de fuentes de OS X.
  2. Volcar las métricas de fuentes en un archivo: ftxdumperfuser -t hhea -A d YOUR_FONT.ttf
  3. Abra el archivo volcado en un editor.
  4. Edite la ascenderpropiedad agregando el valor de la lineGappropiedad. Por ejemplo, si lineGapes 200 y ascenderes 750, haz el ascender950.
  5. Establezca el lineGapen 0.
  6. Fusionar los cambios en la fuente: ftxdumperfuser -t hhea -A f YOUR_FONT.ttf

Una vez que haga esto, es posible que deba ajustar su interfaz de usuario en consecuencia.


4

Tuvimos el mismo problema con una de nuestras fuentes personalizadas. También "arreglamos" el problema editando la propiedad de fuente ascendente. Sin embargo, descubrimos que esto creaba otros problemas y problemas de diseño. Por ejemplo, establecer dinámicamente la altura de la celda en función de la altura de la etiqueta explotaría al usar nuestra fuente editada por ascendente.

Lo que terminamos haciendo fue cambiar la propiedad UIButton contentEdgetInsets.

yourButton.contentEdgeInsets = UIEdgeInsetsMake(-10, 0, 0, 0);

No estoy seguro de qué método es mejor, pero solo quería compartir otra forma de solucionar el problema.


2
convenido. La corrección de la propiedad ascendente no es la solución ideal
Max MacLeod

1
Hola Joshua, acabo de publicar un método que podría solucionar el problema que mencionaste. En resumen, es necesario modificar algunas propiedades más junto con el ascendedor.
Joseph Lin

4
  1. Descargue e instale las herramientas de fuentes de Apple aquí: https://developer.apple.com/downloads/index.action?q=font (el enlace de descarga está en la parte inferior)
  2. Abra la terminal y cd hasta donde está su fuente
  3. Ejecute este comando: ftxdumperfuser -t hhea -A d MY_FONT_NAME.ttf
  4. Ahora tiene un archivo xml con algunas de las propiedades de la fuente, edítelo en su editor de texto
  5. Busque la propiedad "lineGap" y agregue 200 a su valor
  6. Guarde el archivo xml
  7. Ejecute este comando: ftxdumperfuser -t hhea -A f MY_FONT_NAME.ttf
  8. Eliminar el archivo xml
  9. Pruebe la fuente configurada en iOS 6 y vea si se ve mejor.
  10. Si lo necesita, puede volver al paso 3 y sumar / restar a la propiedad "lineGap". (Terminé agregando 250 a mi configuración)

4

Para aquellos que ejecutan OS X El Capitan y llegan a este hilo, es posible que hayan notado que Apple Font Tool Suite ya no es compatible (al menos por ahora).

Pero aún puede realizar los cambios descritos por kolyuchiy y Joseph Lin con el software gratuito de edición de fuentes FontForge .

Abra la fuente con FontForge y seleccione Elemento en el menú superior, luego vaya a Información de fuente> OS / 2> Métricas. Allí desea editar los valores de HHEad Line Gap y HHead Ascent Offset.

Una vez que haya realizado las ediciones necesarias, puede exportar la fuente en Archivo> Generar fuentes y seleccionar el formato de fuente correcto


3

Gracias a esta respuesta , solucioné mi problema con Glyphs, pero de manera un poco diferente.

Abrí mi fuente con Glyphs (también funciona con Glyphs mini) y encontré esta sección allí (esto de Glyphs mini, para llegar presione el botón i en la esquina superior derecha):

ingrese la descripción de la imagen aquí

Simplemente elimine todas estas zonas de alineación (o algunas de ellas) y solucionará este problema. Funcionó perfectamente para mí.


2

Crear texto atribuido a partir del texto de sus etiquetas fue la solución para mí. Aquí hay una extensión:

extension UILabel {
    /// You can call with or without param values; without will use default 2.0
    func setLineSpacing(lineSpacing: CGFloat = 2.0, lineHeightMultiple: CGFloat = 2.0) {
        guard let labelText = self.text else { return }
        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.lineSpacing = lineSpacing
        paragraphStyle.lineHeightMultiple = lineHeightMultiple
        let attributedString:NSMutableAttributedString
        if let labelattributedText = self.attributedText {
            attributedString = NSMutableAttributedString(attributedString: labelattributedText)
        } else {
            attributedString = NSMutableAttributedString(string: labelText)
        }
        // (Swift 4.2 and above) Line spacing attribute
        attributedString.addAttribute(NSAttributedString.Key.paragraphStyle, value:paragraphStyle, range:NSMakeRange(0, attributedString.length))
        self.attributedText = attributedString
    }
}

Para mi fuente personalizada obtuve el resultado que necesito de:

self.myLabel.setLineSpacing(lineSpacing: 1.2, lineHeightMultiple: 1.2)

Esto funciona utilizando el nativo proporcionado NSMutableParagraphStyle()que contiene la altura de la línea y las propiedades de espaciado (que también son accesibles como @IBOutletpropiedades en el Storyboard si no está programando sus etiquetas).


1

¿Has probado Core Text ? He tenido cierto éxito renderizando fuentes personalizadas a través de Core Text, pero no sé si encajaría en su situación.


1
Puedo confirmar que el texto principal no tiene este problema.
floreciente


0

Si tiene problemas con estas utilidades de línea de comandos, pruebe fontcreator en la ventana. y cambiar el asistente de fuente desde su menú de configuración.


0

Para cualquiera que tenga dificultades para usar ftxdumperfuser( kolyuchiy answer) en Mac OS Mojave debido al error de comando no encontrado:

  • Descargue el paquete de herramientas de fuentes de Apple. Los encontré en https://developer.apple.com/download/more/?q=font , elegí el de XCode 11.
  • Monte el archivo dmg
  • Ingrese la imagen del disco cd / Volumes / macOS \ Font \ Tools
  • Extraiga el paquete en una carpeta de su elección: pkgutil --expand-full macOS \ Font \ Tools.pkg ~ / font-tools
  • Las herramientas CLI ahora están disponibles en ~ / font-tools / FontCommandLineTools.pkg / Payload, puede agregar la carpeta a su ruta ( export PATH="$PATH:$HOME/font-tools/FontCommandLineTools.pkg/Payload") o copiar las utilidades a su carpeta bin.

-3

Tuve un problema similar con la fuente icónica "FontAwesome" en mi juego Sprite Kit. Establecer la propiedad SKLabelVerticalAlignmentMode de SKLabelNode en .Center funcionó para mí.

myLabel.verticalAlignmentMode = SKLabelVerticalAlignmentMode.Center

Solo quería compartir en caso de que alguien tuviera el mismo problema.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.