Pregunta ¿Puedo incrustar una fuente personalizada en una aplicación de iPhone?


Esta pregunta se refiere a iOS pre-3.2. A partir del 3.2, esta funcionalidad es fácilmente alcanzable usando la respuesta de samvermette a continuación, y he cambiado la respuesta aceptada (del comando a samvermette) para reflejar esto. No puedo dar crédito a ambas respuestas (además de los votos a favor) pero ambas son buenas.

Me gustaría que una aplicación incluyera una fuente personalizada para renderizar texto, cárguela y luego úsela con estándar UIKit elementos como UILabel. es posible?

Encontré enlaces a continuación:

pero esto me obligaría a renderizar cada glifo, lo cual es demasiado trabajo duro, especialmente para texto de varias líneas.

También encontré publicaciones que dicen directamente que no es posible, pero sin justificación, así que estoy buscando una respuesta definitiva.


EDITAR - ha fallado -[UIFont fontWithName:size:] experimentar

Descargué Harrowprint.tff (descargado de aquí) y lo agregué a mi directorio de Recursos y al proyecto. Luego probé este código:

UIFont* font = [UIFont fontWithName:@"Harrowprint" size:20];

que resultó en una excepción lanzada. Al mirar el archivo TTF en Finder confirmó que el nombre de la fuente era Harrowprint.


EDITAR -Ha habido varias respuestas hasta ahora que me dicen que lea la documentación en X o Y. He experimentado mucho con todo esto y no he llegado a ninguna parte. En un caso, X resultó ser relevante solo en OS X, no en iPhone. En consecuencia, estoy estableciendo una recompensa por esta pregunta, y otorgaré la recompensa a la primera persona que proporcione una respuesta (utilizando solo API documentadas) que responda con información suficiente para que esto funcione en el dispositivo. Trabajar en el simulador también sería una ventaja.


EDITAR - Parece que la recompensa se otorga automáticamente a la respuesta con el mayor número de votos. Interesante. En realidad, nadie proporcionó una respuesta que resolvió la pregunta como se le preguntó, la solución que implica la codificación de su propia UILabel La subclase no es compatible con el ajuste de palabras, que es una característica esencial para mí, aunque creo que podría ampliarlo para hacerlo.


738
2017-12-11 20:21


origen


Respuestas:


iOS 3.2 y versiones posteriores soportan esto. Directamente desde el Lo nuevo en iPhone OS 3.2 doc:

Soporte de fuente personalizada
  Las aplicaciones que desean utilizar fuentes personalizadas ahora pueden incluir esas fuentes en su paquete de aplicaciones y registrar esas fuentes con el sistema incluyendo la clave UIAppFonts en su archivo Info.plist. El valor de esta clave es una matriz de cadenas que identifica los archivos de fuente en el paquete de la aplicación. Cuando el sistema ve la clave, carga las fuentes especificadas y las pone a disposición de la aplicación.

Una vez que las fuentes se han establecido en el Info.plist, puede usar sus fuentes personalizadas como cualquier otra fuente en IB o programáticamente.

Hay un hilo continuo en los foros de desarrolladores de Apple:
https://devforums.apple.com/thread/37824 (Necesario iniciar sesión)

Y aquí hay un excelente y sencillo tutorial de 3 pasos sobre cómo lograr esto (se eliminó el enlace roto)

  1. Agregue sus archivos de fuentes personalizados a su proyecto usando Xcode como recurso
  2. Agrega una clave a tu Info.plist archivo llamado UIAppFonts.
  3. Haz que esta tecla sea una matriz
  4. Para cada fuente que tenga, ingrese el nombre completo de su archivo de fuente (incluida la extensión) como elementos para el UIAppFonts formación
  5. Salvar Info.plist
  6. Ahora en su aplicación, simplemente puede llamar [UIFont fontWithName:@"CustomFontName" size:12] para obtener la fuente personalizada para usar con su UILabels y UITextViews, etc ...

Además: Asegúrese de que las fuentes estén en sus Recursos de paquete de copia.


624
2018-04-11 05:01



Editar: A partir de iOS 3.2, esta funcionalidad está incorporada. Si necesita admitir pre-3.2, aún puede usar esta solución.

Creé un módulo simple que se extiende UILabel y maneja la carga de archivos .ttf. Lancé el código abierto bajo la licencia de Apache y lo puse en github Aquí. 

Los archivos importantes son FontLabel.h y FontLabel.m.

Utiliza parte del código de La respuesta de Genericrich.

Navega por la fuente Aquí.

O

  • Copie su archivo de fuente en recursos

  • Agrega una clave a tu Info.plist archivo llamado UIAppFonts. ("Fuentes proporcionadas por la aplicación)

  • Haz que esta tecla sea una matriz

  • Para cada fuente que tenga, ingrese el nombre completo de su archivo de fuente (incluida la extensión) como elementos de la matriz UIAppFonts

  • Salvar Info.plist

  • Ahora en su aplicación, simplemente puede llamar [UIFont fontWithName:@"CustomFontName" size:15] para obtener la fuente personalizada para usar con su UILabels y UITextViews, etc ...

Para más información


290
2018-04-30 21:57



Hay una manera simple de usar fuentes personalizadas en iOS 4.

  1. Agregue su archivo de fuente (por ejemplo, Chalkduster.ttf) a Recursos carpeta del proyecto en XCode.
  2. Abierto info.plist y agrega una nueva clave llamada UIAppFonts. El tipo de esta clave debe ser una matriz.
  3. Agregue su nombre de fuente personalizado a esta matriz, incluida la extensión (Chalkduster.ttf)
  4. Ahora puedes usar [UIFont fontWithName:@"Chalkduster" size:16] en tu aplicación.

Desafortunadamente, IB no permite inicializar etiquetas con fuentes personalizadas. Ver esta pregunta para resolver este problema. Mi solución favorita es usar personalizado UILabel subclase:

@implementation CustomFontLabel

- (id)initWithCoder:(NSCoder *)decoder
{
    if (self = [super initWithCoder: decoder])
    {
        [self setFont: [UIFont fontWithName: @"Chalkduster" size: self.font.pointSize]];
    }
    return self;
}

@end

112
2017-07-07 21:05



En Info.plist, agregue la entrada "Fuentes proporcionadas por la aplicación" e incluya los nombres de las fuentes como cadenas:

Fonts provided by application
           Item 0        myfontname.ttf
           Item 1        myfontname-bold.ttf
           ...

Luego verifique que su fuente esté incluida ejecutando:

for (NSString *familyName in [UIFont familyNames]) {
    for (NSString *fontName in [UIFont fontNamesForFamilyName:familyName]) {
         NSLog(@"%@", fontName);
    }
}

Tenga en cuenta que su nombre de archivo ttf puede no ser el mismo nombre que usa cuando establece la fuente para su etiqueta (puede usar el código anterior para obtener el parámetro "fontWithName"):

[label setFont:[UIFont fontWithName:@"MyFontName-Regular" size:18]];

50
2017-10-17 13:29



editar: esta respuesta ha desaparecido a partir de iOS3.2; usa UIAppFonts

La única forma en que he podido cargar de manera personalizada UIFonts es a través del marco privado GraphicsServices.

Lo siguiente cargará todo .ttf fuentes en el paquete principal de la aplicación:

BOOL GSFontAddFromFile(const char * path);
NSUInteger loadFonts()
{
    NSUInteger newFontCount = 0;
    for (NSString *fontFile in [[NSBundle mainBundle] pathsForResourcesOfType:@"ttf" inDirectory:nil])
        newFontCount += GSFontAddFromFile([fontFile UTF8String]);
    return newFontCount;
}

Una vez que se cargan las fuentes, se pueden usar como las fuentes proporcionadas por Apple:

NSLog(@"Available Font Families: %@", [UIFont familyNames]);
[label setFont:[UIFont fontWithName:@"Consolas" size:20.0f]];

GraphicsServices incluso se puede cargar en tiempo de ejecución en caso de que la API desaparezca en el futuro:

#import <dlfcn.h>
NSUInteger loadFonts()
{
    NSUInteger newFontCount = 0;
    NSBundle *frameworkBundle = [NSBundle bundleWithIdentifier:@"com.apple.GraphicsServices"];
    const char *frameworkPath = [[frameworkBundle executablePath] UTF8String];
    if (frameworkPath) {
        void *graphicsServices = dlopen(frameworkPath, RTLD_NOLOAD | RTLD_LAZY);
        if (graphicsServices) {
            BOOL (*GSFontAddFromFile)(const char *) = dlsym(graphicsServices, "GSFontAddFromFile");
            if (GSFontAddFromFile)
                for (NSString *fontFile in [[NSBundle mainBundle] pathsForResourcesOfType:@"ttf" inDirectory:nil])
                    newFontCount += GSFontAddFromFile([fontFile UTF8String]);
        }
    }
    return newFontCount;
}

35
2018-04-30 23:25



Con iOS 8+ y Xcode 6+ puedes hacer esto fácilmente Estos son los pasos:

1) Arrastra y suelta tu fuente a Xcode Soporte de la carpeta de archivos. No te olvides de marcar tu aplicación en Agregar a objetivos sección. A partir de este momento, puede usar esta fuente en IBy elígelo desde el palet de fuentes.

enter image description here

2) Para hacer que esta fuente esté disponible en su dispositivo, abra su info.plist y añadir Fonts provided by application llave. Contendrá la clave del elemento 0, debe agregar el nombre de su fuente como valor. El nombre de la fuente puede variar de tu nombre de archivo de fuente. Pero primero, intente agregar su nombre de archivo en la mayoría de los casos este trabajo.

enter image description here

Si no, Este artículo siempre me ayudó

Aquí hay un fragmento rápido del código de este artículo para ayudarlo a encontrar el nombre de su fuente.

func allFonts(){

   for family in UIFont.familyNames(){

       println(family)


       for name in UIFont.fontNamesForFamilyName(family.description)
       {
           println("  \(name)")
       }

   }

}

EDITAR

Quiero mencionar que necesita agregar archivos de fuentes a su Fases de construcción del objetivo, Copie los recursos del paquete. Sin él, no verá su fuente en el dispositivo. Y podría conducir a un comportamiento inesperado.

Por ejemplo, encuentro un bug, cuando UITextField tiene una fuente personalizada, pero esta fuente no estaba en el Copie los recursos del paquete. Y cuando paso al viewcontroller con este textfield, hay un retraso de unos 4 segundos antes viewDidLoad función fue llamada. La resolución de problemas con las fuentes eliminó este retraso. Por lo tanto, recomendamos comprobarlo dos veces. (rdar: // 20028250) Por cierto, no pude reproducir el error, pero estoy seguro de que ese problema fue con la fuente.


30
2017-09-02 08:08



He hecho esto así:

Cargue la fuente:

- (void)loadFont{
  // Get the path to our custom font and create a data provider.
  NSString *fontPath = [[NSBundle mainBundle] pathForResource:@"mycustomfont" ofType:@"ttf"]; 
  CGDataProviderRef fontDataProvider = CGDataProviderCreateWithFilename([fontPath UTF8String]);

  // Create the font with the data provider, then release the data provider.
  customFont = CGFontCreateWithDataProvider(fontDataProvider);
  CGDataProviderRelease(fontDataProvider); 
}

Ahora, en tu drawRect:, haz algo como esto:

-(void)drawRect:(CGRect)rect{
    [super drawRect:rect];
    // Get the context.
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextClearRect(context, rect);
    // Set the customFont to be the font used to draw.
    CGContextSetFont(context, customFont);

    // Set how the context draws the font, what color, how big.
    CGContextSetTextDrawingMode(context, kCGTextFillStroke);
    CGContextSetFillColorWithColor(context, self.fontColor.CGColor);
    UIColor * strokeColor = [UIColor blackColor];
    CGContextSetStrokeColorWithColor(context, strokeColor.CGColor);
    CGContextSetFontSize(context, 48.0f);

    // Create an array of Glyph's the size of text that will be drawn.
    CGGlyph textToPrint[[self.theText length]];

    // Loop through the entire length of the text.
    for (int i = 0; i < [self.theText length]; ++i) {
        // Store each letter in a Glyph and subtract the MagicNumber to get appropriate value.
        textToPrint[i] = [[self.theText uppercaseString] characterAtIndex:i] + 3 - 32;
    }
    CGAffineTransform textTransform = CGAffineTransformMake(1.0, 0.0, 0.0, -1.0, 0.0, 0.0);
    CGContextSetTextMatrix(context, textTransform);
    CGContextShowGlyphsAtPoint(context, 20, 50, textToPrint, [self.theText length]);
}

Básicamente tienes que hacer un poco de fuerza bruta recorriendo el texto y estudiando el número mágico para encontrar tu compensación (aquí, mírame usando 29) en la fuente, pero funciona.

Además, debe asegurarse de que la fuente sea legalmente incrustable. La mayoría no lo son y hay abogados que se especializan en este tipo de cosas, así que ten cuidado.


26
2017-12-16 01:28