web-dev-qa-db-fra.com

La police installée personnalisée ne s'affiche pas correctement dans UILabel

J'essaie d'utiliser un Helvetica Neue Condensed font que j'ai reçu du package Adobe Font Collection Pro. Malheureusement, il semble dessiner de manière incorrecte lorsque je l’utilise dans une UILabel.

La hauteur de ligne semble être calculée correctement (je pense), mais lorsque la police est affichée, elle est alignée tout en haut du cadre de sélection. J'ai appelé [myLabel sizeToFit] et seulement ajusté la largeur pour produire cette capture d'écran:

Screen capture of incorrect font rendering

J'ai eu le même problème avec la version en gras et régulière de la police. J'ai réussi à extraire une version de Helvetica Neue Bold à partir de OSX et à la mettre sur mon appareil. Elle s'affiche correctement (arrière-plan vert dans l'image ci-dessus).

Qu'est-ce qui ne va pas avec le fichier de police ou mon code qui le ferait dessiner de cette façon?

76
MikeQ

J'ai posté une solution qui consiste à patcher le fichier de police ttf ici :

Voici la solution qui a fonctionné pour ma police personnalisée qui avait le même problème dans UILabel, UIButton, etc. Le problème avec la police s'est avéré être le fait que sa propriété ascender était trop petite par rapport à la valeur des polices système. Ascender est un espace vertical au-dessus des caractères de la police. Pour réparer votre police, vous devez télécharger Apple Font Tool Suite utilitaires de ligne de commande. Ensuite, prenez votre police et procédez comme suit:

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

Cela va créer Bold.hhea.xml. Ouvrez-le avec un éditeur de texte et augmentez la valeur de l'attribut ascender. Vous devrez expérimenter un peu pour trouver la valeur exacte qui vous convient le mieux. Dans mon cas, je l'ai changé de 750 à 1200. Exécutez à nouveau l'utilitaire avec la ligne de commande suivante pour fusionner vos modifications dans le fichier ttf:

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

Ensuite, utilisez simplement la police ttf obtenue dans votre application.

116
kolyuchiy

Donc, ceci est une version modifiée de la réponse de kolyuchiy.

J'ai ouvert ma police avec Glyphs , puis je l'ai exportée sans rien modifier. Comme par magie, le problème de l'alignement vertical avait disparu! 

Le mieux est que la nouvelle police fonctionne bien avec des méthodes telles que sizeWithFont:, de sorte qu’elle n’a pas les problèmes mentionnés par Joshua.

J'ai jeté un coup d'œil à la table HHEA avec la commande kolyuchiy mentionnée et j'ai remarqué que les glyphes modifiaient non seulement ascender, mais également lineGap et numberOfHMetrics pour moi.

Voici les données brutes, avant:

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"

et aprè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"

Ainsi, la morale de l'histoire ne consiste pas seulement à augmenter le nombre de victimes, mais également à modifier d'autres valeurs connexes. 

Je ne suis pas un expert en typographie, donc je ne peux pas vraiment expliquer le pourquoi et le comment. Si quelqu'un peut fournir une meilleure explication, ce serait grandement apprécié! :)

64
Joseph Lin

iOS 6 respecte la propriété lineGap de la police, tandis qu'iOS 7 l'ignore. Ainsi, seules les polices personnalisées avec un espacement égal à 0 fonctionneront correctement sous les deux systèmes d'exploitation.

La solution est de rendre le lineGap 0 et d’augmenter le montant en conséquence. Selon la réponse ci-dessus, une solution consiste à importer et à exporter à partir de glyphes. Cependant, notez qu'une future version de l'application pourrait résoudre ce "bogue".

Une solution plus robuste consiste à éditer vous-même la police, par ce post . Plus précisément,

  1. Installez les outils de polices OS X.
  2. Videz les métriques de police dans un fichier: ftxdumperfuser -t hhea -A d YOUR_FONT.ttf
  3. Ouvrez le fichier vidé dans un éditeur.
  4. Editez la propriété ascender en lui ajoutant la valeur de la propriété lineGap. Par exemple, si lineGap est 200 et si ascender est 750, définissez ascender 950.
  5. Définissez la lineGap sur 0.
  6. Fusionner les modifications dans la police: ftxdumperfuser -t hhea -A f YOUR_FONT.ttf

Cela fait, vous devrez peut-être ajuster votre interface utilisateur en conséquence.

31
phatmann

Pour ceux qui utilisent OS X El Capitan et qui abordent ce sujet, vous avez peut-être remarqué que la suite Apple Font Tool n'est plus compatible (du moins pour le moment). 

Mais vous pouvez toujours effectuer les modifications décrites par kolyuchiy et Joseph Lin avec le logiciel d'édition de polices gratuit FontForge .

Ouvrez la police avec FontForge et sélectionnez Élément dans le menu supérieur, puis sélectionnez Informations sur la police> OS/2> Métriques. Là vous voulez éditer les valeurs HHEad Line Gap et HHead Ascent Offset.

Une fois que vous avez apporté les modifications nécessaires, vous pouvez simplement exporter la police dans Fichier> Générer des polices et sélectionner le bon format de police.

4
Naiko
  1. Téléchargez et installez les outils de polices Apple ici: https://developer.Apple.com/downloads/index.action?q=font (le lien de téléchargement est en bas)
  2. Ouvrez le terminal et dirigez-vous vers votre police.
  3. Exécutez cette commande: ftxdumperfuser -t hhea -A d MY_FONT_NAME.ttf
  4. Maintenant vous avez un fichier XML avec certaines propriétés de la police, éditez-le dans votre éditeur de texte
  5. Recherchez la propriété "lineGap" et ajoutez 200 à sa valeur
  6. Enregistrer le fichier XML
  7. Exécutez cette commande: ftxdumperfuser -t hhea -A f MY_FONT_NAME.ttf
  8. Supprimer le fichier XML
  9. Essayez la police configurée sur iOS 6 et voyez si elle a l'air meilleure.
  10. Si vous en avez besoin, vous pouvez revenir à l'étape 3 et ajouter/soustraire à la propriété "lineGap". (J'ai fini par ajouter 250 à ma configuration)
4
nurxyz

Merci à ceci réponse J'ai résolu mon problème avec les glyphes, mais un peu différemment.

J'ai ouvert ma police avec Glyphs (fonctionne également avec Glyphs mini) et j'ai trouvé cette section là (ceci provient de Glyphs mini, pour y arriver, appuyez sur le bouton i dans le coin supérieur droit):

enter image description here

Supprimez simplement toutes ces zones d'alignement (ou certaines d'entre elles) et le problème à résoudre sera résolu . A parfaitement fonctionné pour moi.

3
DevilPinky

Nous avons eu le même problème avec l'une de nos polices personnalisées. Nous avons également "corrigé" le problème en modifiant la propriété font ascender. Cependant, nous avons constaté que cela créait d'autres problèmes et problèmes de mise en page. Par exemple, définir dynamiquement la hauteur de cellule en fonction de la hauteur de l'étiquette exploserait si vous utilisiez notre police modifiée Ascender. 

Nous avons fini par modifier la propriété UIButton contentEdgetInsets. 

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

Vous ne savez pas quelle méthode est la meilleure, mais je voulais simplement partager un autre moyen de résoudre le problème. 

3
Joshua Dance

Avez-vous essayé Core Text ? J'ai réussi à rendre des polices personnalisées avec Core Text, mais je ne sais pas si cela conviendrait à votre situation.

1
RyanR

Créer un texte attribué à partir de vos étiquettes a été la solution pour moi. Heres une extension:

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

Pour ma police personnalisée, j'ai obtenu le résultat dont j'ai besoin:

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

Cela fonctionne en utilisant la NSMutableParagraphStyle() fournie en natif, qui contient les propriétés de hauteur de ligne et d'espacement (accessibles en tant que propriétés @IBOutlet dans le Storyboard également si vous ne programmez pas vos étiquettes). 

0
App Dev Guy

Si vous rencontrez des problèmes avec ces utilitaires de ligne de commande, essayez fontcreator on window. et changez l'assesseur de polices à partir de son menu de réglage.

0
Gaurav