Question Puis-je intégrer une police personnalisée dans une application iPhone?


Cette question concerne iOS pré-3.2. À partir de la version 3.2, cette fonctionnalité est facilement réalisable en utilisant la réponse de samvermette ci-dessous, et j'ai changé la réponse acceptée (de commande en samvermette) pour refléter cela. Je ne peux pas donner de crédit aux deux réponses (en dehors des upvotes), mais ils sont tous les deux bons.

Je voudrais avoir une application inclure une police personnalisée pour le rendu du texte, le charger, puis l'utiliser avec la norme UIKit des éléments comme UILabel. Est-ce possible?

J'ai trouvé ci-dessous des liens:

mais cela exigerait que je rende moi-même chaque glyphe, ce qui est un peu trop dur, spécialement pour le texte multi-lignes.

J'ai aussi trouvé des articles qui disent carrément que ce n'est pas possible, mais sans justification, alors je cherche une réponse définitive.


MODIFIER - échoué -[UIFont fontWithName:size:] expérience

J'ai téléchargé Harrowprint.tff (téléchargé à partir de ici) et l'a ajouté à mon répertoire Ressources et au projet. J'ai ensuite essayé ce code:

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

ce qui a entraîné une exception étant levée. Regarder le fichier TTF dans le Finder a confirmé que le nom de la police était Harrowprint.


MODIFIER - Il y a eu un certain nombre de réponses à ce jour qui me disent de lire la documentation sur X ou Y. J'ai expérimenté abondamment avec tout ceci et je n'ai obtenu nulle part. Dans un cas, X s'est avéré pertinent uniquement sur OS X, pas sur iPhone. Par conséquent, je mets une prime pour cette question, et je vais attribuer la prime à la première personne qui fournit une réponse (en utilisant seulement des API documentées) qui répond avec suffisamment d'informations pour que cela fonctionne sur l'appareil. Travailler sur le simulateur serait aussi un bonus.


MODIFIER - Il semble que la prime récompense automatiquement la réponse avec le plus grand nombre de votes. Intéressant. Personne n'a fourni de réponse à la question posée, la solution qui consiste à coder la vôtre. UILabel la sous-classe ne prend pas en charge le traitement de texte, ce qui est une caractéristique essentielle pour moi - même si je suppose que je pourrais l'étendre pour le faire.


738
2017-12-11 20:21


origine


Réponses:


iOS 3.2 et ultérieur supportent ceci. Directement du Quoi de neuf dans iPhone OS 3.2 doc:

Support de polices personnalisé
  Les applications qui souhaitent utiliser des polices personnalisées peuvent maintenant inclure ces polices dans leur groupe d'applications et enregistrer ces polices avec le système en incluant la clé UIAppFonts dans leur fichier Info.plist. La valeur de cette clé est un tableau de chaînes identifiant les fichiers de polices dans l'ensemble de l'application. Lorsque le système voit la clé, il charge les polices spécifiées et les met à la disposition de l'application.

Une fois les polices définies dans le Info.plist, vous pouvez utiliser vos polices personnalisées comme n'importe quelle autre police dans IB ou par programmation.

Il y a un fil conducteur sur les Forums des développeurs Apple:
https://devforums.apple.com/thread/37824 (Connexion requise)

Et voici un excellent et simple tutoriel en 3 étapes sur la façon d'y parvenir (lien brisé enlevé)

  1. Ajoutez vos fichiers de police personnalisés dans votre projet en utilisant Xcode comme ressource
  2. Ajouter une clé à votre Info.plist fichier appelé UIAppFonts.
  3. Faire de cette clé un tableau
  4. Pour chaque police que vous avez, entrez le nom complet de votre fichier de police (y compris l'extension) en tant qu'éléments UIAppFonts tableau
  5. sauvegarder Info.plist
  6. Maintenant, dans votre application, vous pouvez simplement appeler [UIFont fontWithName:@"CustomFontName" size:12] pour obtenir la police personnalisée à utiliser avec votre UILabels et UITextViews, etc…

Aussi: Assurez-vous que les polices sont dans vos ressources Bundle de copie.


624
2018-04-11 05:01



Edit: À partir de iOS 3.2, cette fonctionnalité est intégrée. Si vous devez prendre en charge pré-3.2, vous pouvez toujours utiliser cette solution.

J'ai créé un module simple qui étend UILabel et gère le chargement des fichiers .ttf. Je l'ai libéré opensource sous la licence Apache et le mettre sur github Ici. 

Les fichiers importants sont FontLabel.h et FontLabel.m.

Il utilise une partie du code de La réponse de Genericrich.

Parcourir la source Ici.

OU

  • Copiez votre fichier de police dans les ressources

  • Ajouter une clé à votre Info.plist fichier appelé UIAppFonts. ("Polices fournies par l'application)

  • Faire de cette clé un tableau

  • Pour chaque police que vous avez, entrez le nom complet de votre fichier de police (y compris l'extension) en tant qu'éléments dans le tableau UIAppFonts

  • sauvegarder Info.plist

  • Maintenant, dans votre application, vous pouvez simplement appeler [UIFont fontWithName:@"CustomFontName" size:15] pour obtenir la police personnalisée à utiliser avec votre UILabels et UITextViews, etc…

Pour plus d'informations


290
2018-04-30 21:57



Il existe un moyen simple d'utiliser des polices personnalisées dans iOS 4.

  1. Ajoutez votre fichier de police (par exemple, Chalkduster.ttf) à Ressources dossier du projet en XCode.
  2. Ouvrir info.plist et ajoutez une nouvelle clé appelée UIAppFonts. Le type de cette clé doit être array.
  3. Ajoutez votre nom de police personnalisé à ce tableau, y compris l'extension (Chalkduster.ttf).
  4. Maintenant vous pouvez utiliser [UIFont fontWithName:@"Chalkduster" size:16] dans votre application.

Malheureusement, IB ne permet pas d'initialiser les étiquettes avec des polices personnalisées. Voir cette question pour résoudre ce problème. Ma solution préférée est d'utiliser la coutume UILabel sous-classe:

@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



Dans Info.plist, ajoutez l'entrée "Polices fournies par l'application" et incluez les noms de police en tant que chaînes:

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

Ensuite, vérifiez que votre police est incluse en exécutant:

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

Notez que votre nom de fichier ttf n'est peut-être pas le même que celui que vous utilisez lorsque vous définissez la police de votre étiquette (vous pouvez utiliser le code ci-dessus pour obtenir le paramètre "fontWithName"):

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

50
2017-10-17 13:29



edit: Cette réponse est supprimée à partir de iOS3.2; utiliser UIAppFonts

La seule façon dont j'ai réussi à charger mes clients UIFonts est via le framework privé GraphicsServices.

Ce qui suit chargera tous les .ttf polices dans le bundle principal de l'application:

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;
}

Une fois les polices chargées, elles peuvent être utilisées comme les polices fournies par Apple:

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

GraphicsServices peut même être chargé au moment de l'exécution au cas où l'API disparaîtrait à l'avenir:

#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



Avec iOS 8+ et Xcode 6+ vous pouvez le faire facilement. Voici les étapes:

1) Glissez et déposez votre police à Xcode Dossier de soutien de fichiers. N'oubliez pas de marquer votre application à Ajouter aux cibles section. A partir de ce moment, vous pouvez utiliser cette police dans IBet choisissez-le à partir de la palette de polices.

enter image description here

2) Pour que cette police soit disponible sur votre appareil, ouvrez votre info.plist et ajouter Fonts provided by application clé. Il contiendra la clé de l'article 0, vous devez ajouter votre nom de police en tant que valeur. Le nom de la police peut varier du nom de votre fichier de police. Mais d'abord, essayez d'ajouter votre nom de fichier dans la plupart des cas ce travail.

enter image description here

Si non, Cet article m'a toujours aidé.

Voici un extrait rapide du code de cet article pour vous aider à trouver votre nom de police.

func allFonts(){

   for family in UIFont.familyNames(){

       println(family)


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

   }

}

MODIFIER

Je veux mentionner, que vous devez ajouter des fichiers de polices à votre Phases de construction de la cible, Copier les ressources du regroupement. Sans cela, vous ne verrez pas votre police sur l'appareil. Et cela pourrait conduire à un comportement inattendu.

Par exemple, je rencontre un bug, quand UITextField avoir une police personnalisée, mais cette police n'était pas dans le Copier les ressources du regroupement. Et quand je me lie à la viewcontroller avec ça textfield, il y a un délai d'environ 4 secondes avant viewDidLoad la fonction a été appelée. La résolution des problèmes de polices a supprimé ce délai. Donc, recommande de le vérifier deux fois. (rdar: // 20028250) Btw, je n'étais pas capable de reproduire le bug, mais je suis sûr que ce problème était avec la police.


30
2017-09-02 08:08



Je l'ai fait comme ceci:

Chargez la police:

- (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); 
}

Maintenant, dans votre drawRect:, fais quelque chose comme ça:

-(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]);
}

Fondamentalement, vous devez faire un peu de force brute en boucle à travers le texte et farzing environ avec le nombre magique pour trouver votre décalage (ici, voyez-moi en utilisant 29) dans la police, mais cela fonctionne.

En outre, vous devez vous assurer que la police est légalement intégrable. La plupart ne le sont pas et il y a des avocats qui se spécialisent dans ce genre de choses, alors soyez prévenus.


26
2017-12-16 01:28