web-dev-qa-db-fra.com

La chaîne attribuée aux polices personnalisées dans le storyboard ne se charge pas correctement

Nous utilisons des polices personnalisées dans notre projet. Cela fonctionne bien dans Xcode 5. Dans Xcode 6, cela fonctionne en texte brut, avec une chaîne de caractères attribuée dans le code. Mais ces chaînes attribuées définies dans le storyboard sont toutes liées à Helvetica lors de l'exécution sur un simulateur ou un appareil, bien qu'elles aient l'air bien dans le storyboard.

Je ne sais pas s'il s'agit d'un bogue du SDK Xcode 6 ou iOS 8, ou si la manière d'utiliser les polices personnalisées est modifiée dans Xcode 6/iOS 8?

96
Allen Hsu

Le correctif pour moi était d’utiliser une classe IBDesignable:

import UIKit

@IBDesignable class TIFAttributedLabel: UILabel {

    @IBInspectable var fontSize: CGFloat = 13.0

    @IBInspectable var fontFamily: String = "DIN Light"

    override func awakeFromNib() {
        var attrString = NSMutableAttributedString(attributedString: self.attributedText)
        attrString.addAttribute(NSFontAttributeName, value: UIFont(name: self.fontFamily, size: self.fontSize)!, range: NSMakeRange(0, attrString.length))
        self.attributedText = attrString
    }
}

En vous donnant ceci dans le constructeur d'interface:

Interface Builder custom font with attributed string

Vous pouvez configurer votre chaîne attribuée comme vous le feriez normalement, mais vous devrez redéfinir votre taille de police et votre famille de polices dans les nouvelles propriétés disponibles.

Comme Interface Builder utilise la police personnalisée par défaut, il en résulte ce que vous voyez être ce que vous obtenez , ce que je préfère lors de la création d'applications.

Note

La raison pour laquelle j'utilise ceci au lieu de la version standard uniquement, c'est que je définis des propriétés sur l'étiquette attribuée, comme le espacement des lignes, qui ne sont pas disponibles lors de l'utilisation du style brut.

30
Antoine

La solution la plus simple pour laquelle vous avez travaillé consiste à faire glisser les polices dans FontBook. Si les polices sont dans votre projet mais pas dans le FontBook de votre ordinateur, IB a parfois du mal à le trouver. Bizarre, mais a travaillé pour moi à plusieurs reprises.

26
Alan Scarpa

Vous pouvez ajouter des polices personnalisées au livre de polices.

Etape 1 : Cliquez sur Gérer les polices. Il ouvre le livre de polices.

enter image description here

Step2 : Cliquez sur plus et ajoutez vos polices.

enter image description here

La prochaine fois que vous cliquerez sur une police avec un texte attribué, la police nouvellement ajoutée apparaîtra également dans la liste. Mais assurez-vous que votre police personnalisée a été ajoutée dans les ressources info.plist et bundle.

10
mahbaleshwar hegde

Grâce à ce fil, je suis arrivé à cette solution:

private let fontMapping = [
    "HelveticaNeue-Medium": "ITCAvantGardePro-Md",
    "HelveticaNeue": "ITCAvantGardePro-Bk",
    "HelveticaNeue-Bold": "ITCAvantGardePro-Demi",
]

func switchFontFamily(string: NSAttributedString) -> NSAttributedString {
    var result = NSMutableAttributedString(attributedString: string)
    string.enumerateAttribute(NSFontAttributeName, inRange: NSRange(location: 0, length: string.length), options: nil) { (font, range, _) in
        if let font = font as? UIFont {
            result.removeAttribute(NSFontAttributeName, range: range)
            result.addAttribute(NSFontAttributeName, value: UIFont(name: fontMapping[font.fontName]!, size: font.pointSize)!, range: range)
        }
    }
    return result
}
5
rexsheng

Ma solution est un peu un travail de contournement. La vraie solution est pour Apple pour réparer Interface Builder.

Avec celui-ci, vous pouvez marquer tout le texte en gras et en italique dans le générateur d'interface à l'aide d'une police système, puis restituer votre police personnalisée au moment de l'exécution. Peut ne pas être optimal dans tous les cas.

 NSMutableAttributedString* ApplyCustomFont(NSAttributedString *attributedText,
                     UIFont* boldFont,
                     UIFont* italicFont,
                     UIFont* boldItalicFont,
                     UIFont* regularFont)
{

    NSMutableAttributedString *attrib = [[NSMutableAttributedString alloc] initWithAttributedString:attributedText];
    [attrib beginEditing];
    [attrib enumerateAttribute:NSFontAttributeName inRange:NSMakeRange(0, attrib.length) options:0
                    usingBlock:^(id value, NSRange range, BOOL *stop)
    {
        if (value)
        {
            UIFont *oldFont = (UIFont *)value;
            NSLog(@"%@",oldFont.fontName);

            [attrib removeAttribute:NSFontAttributeName range:range];

            if([oldFont.fontName rangeOfString:@"BoldItalic"].location != NSNotFound && boldItalicFont != nil)
                [attrib addAttribute:NSFontAttributeName value:boldItalicFont range:range];
            else if([oldFont.fontName rangeOfString:@"Italic"].location != NSNotFound && italicFont != nil)
                [attrib addAttribute:NSFontAttributeName value:italicFont range:range];
            else if([oldFont.fontName rangeOfString:@"Bold"].location != NSNotFound && boldFont != nil)
                [attrib addAttribute:NSFontAttributeName value:boldFont range:range];
            else if(regularFont != nil)
                [attrib addAttribute:NSFontAttributeName value:regularFont range:range];
        }
    }];
    [attrib endEditing];

    return attrib;
}

Inspiré par ce post

4
KidA

Problème rencontré: la police d'attribut définie pour TextView dans le storyboard ne fonctionnait pas à l'exécution avec le SDK XCode 6.1 & iOS 8.

Voici comment j'ai résolu ce problème, pourrait être une solution de contournement pour vous:

  1. ouvrez l'inspecteur d'attributs de votre textview, changez le texte en "Plain"

  2. cliquez sur la croix pour supprimer le "wC hR" (rouge ci-dessous)

    enter image description here

  3. changez le texte en "Attribué", vous pourrez ensuite définir la police et la taille de votre texte.

  4. courir pour vérifier si cela fonctionne
3
Zhihao Yang

J'ai rencontré des difficultés avec ce bogue: UILabel s'affiche correctement dans IB avec une police personnalisée mais ne s'affiche pas correctement sur le périphérique ou le simulateur (la police est incluse dans le projet et utilisée dans les étiquettes UIL ordinaires).

Enfin trouvé Attributed String Creator sur (Mac) App Store. Génère du code à placer dans votre application à l'emplacement approprié. Fantastique. Je ne suis pas le créateur, juste un utilisateur heureux.

3
ghr

Problème rencontré: la police d'attribut pour UILabel dans le storyboard ne fonctionnait pas dans l'exécution. L'utilisation de ce UIFont + IBCustomFonts.m fonctionne pour moi https://github.com/deni2s/IBCustomFonts

2
Praveen Sevta

La solution @Hamidptb fonctionne, assurez-vous d'obtenir le nom correct de la police (une fois que vous l'avez ajoutée à Font Book)

  • Ouvrez l’application Font Book, naviguez jusqu’à votre police, puis appuyez sur Command + I. Le nom PostScript est le nom de la police que vous souhaitez utiliser ici:

    UILabel.appearance (). Font = UIFont (nom: "PostScriptName", taille: 17)

1
itsmcgh

Double-cliquez sur et installez la police sur le système. Cela fonctionnera (Xcode 8.2)

1
Ishara Meegahawala

Le même problème.

Résolu: Il suffit de cocher Sélectionnable dans TextView. Sans cela, j'ai la police système standard.

1
Maselko

Pour toute personne appliquant des polices personnalisées à une chaîne attribuée dans le code: essayez de la définir dans viewDidLayoutSubviews. Mon erreur était de le faire dans viewDidLoad, cela ne sera pas appliqué ici.

0
sergey.syrotynin

En cas de chaîne attribuée, vous pouvez ajouter une police personnalisée à la liste des polices - Cliquez sur l'icône de la police pour afficher la boîte de dialogue suivante. Dans la boîte de dialogue suivante, vous pouvez ajouter votre propre catégorie ou celle existante pour la police personnalisée . boîte de dialogue de police attribuée

Ensuite, cliquez sur Gérer les polices pour ouvrir la boîte de dialogue suivante, sélectionnez la catégorie que vous avez créée ou existante. Cliquez sur le signe + pour ajouter la police dans la catégorie. Gérer le dialogue de police

0
Sunil Singh

c'est une solution simple et rapide, et c'est un travail dans mon cas. cette solution consiste à ajouter une ligne de code dans didFinishLaunchingWithOptions func dans le fichier AppDelegate.Swift:

pour textViews:

UITextView.appearance().font = UIFont(name: "IranSans", size: 17)

pour les étiquettes:

UILabel.appearance().font = UIFont(name: "IranSans", size: 17)

et pour le reste de UiView comme ceci deux two

0
Hamid Reza Ansari

J'essayais d'obtenir des cellules tableView avec du texte comportant plusieurs paragraphes. Les chaînes attribuées semblaient être un moyen d’obtenir un espace supplémentaire entre les paragraphes (quelque chose de plus séduisant que de faire deux sauts de ligne dans la chaîne). Je suis tombé sur ce message et sur d'autres messages lorsque j'ai découvert que les paramètres de l'IB n'étaient pas appliqués au moment de l'exécution lorsque vous vouliez mettre un texte différent dans la cellule.

La principale chose que j’ai suggérée est d’ajouter une extension à String (en utilisant Swift) pour créer une chaîne attribuée avec certaines caractéristiques. Exemple ici utilise la police Marker Felt, car elle se distingue facilement de Helvetica. L'exemple montre également un peu d'espacement supplémentaire entre les paragraphes pour les rendre plus distincts les uns des autres.

extension String {
func toMarkerFelt() -> NSAttributedString {
    var style = NSMutableParagraphStyle()
    style.paragraphSpacing = 5.0
    let markerFontAttributes : [NSObject : AnyObject]? = [
        NSFontAttributeName : UIFont(name: "Marker Felt", size: 14.0)!,
        NSParagraphStyleAttributeName: style,
        NSForegroundColorAttributeName : UIColor.blackColor()
    ]
    let s = NSAttributedString(string: self, attributes: markerFontAttributes)
    return s
    }
}

Ensuite, dans mon objet personnalisé tableViewCell, vous lui envoyez le texte que vous souhaitez et le convertit en chaîne attribuée à UILabel.

//  MarkerFeltCell.Swift
class MarkerFeltCell: UITableViewCell {
@IBOutlet weak var myLabel: UILabel!
func configureCellWithString(inputString : String) {
    myLabel.attributedText = inputString.toMarkerFelt()
}}

Dans le contrôleur de vue avec tableView, vous devez enregistrer votre cellule dans viewDidLoad () - J'ai utilisé un nib, par exemple, quelque chose comme:

let cellName = "MarkerFeltCell"
tableView.registerNib(UINib(nibName: cellName, bundle: nil), forCellReuseIdentifier: cellName)

Pour que la cellule puisse déterminer sa taille, créez une cellule prototype utilisée pour obtenir des informations sur la taille, sans jamais l'ajouter à la tableView. Donc, dans les variables de votre contrôleur de vue:

var prototypeSummaryCell : MarkerFeltCell? = nil

Puis dans (probablement remplacer - en fonction de votre contrôleur de vue) heightForRowAtIndexPath:

override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
        // ...
    if xib == "MarkerFeltCell" {
            if prototypeCell == nil {
                prototypeCell = tableView.dequeueReusableCellWithIdentifier(xib) as? MarkerFeltCell
            }
            let width : CGFloat = tableView.bounds.width
            let height : CGFloat = prototypeCell!.bounds.height
            prototypeCell?.bounds = CGRect(x: 0, y: 0, width: width, height: height)
            configureCell(prototypeCell!, atIndexPath: indexPath)
            prototypeSummaryCell?.layoutIfNeeded()
            let size = prototypeSummaryCell!.contentView.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize)
            let nextHeight : CGFloat = ceil(size.height + 1.0)
            return nextHeight
    } else {  // ...

Dans le code ci-dessus, le prototypeCell sera rempli la première fois qu'il est nécessaire. Le prototypeCell est ensuite utilisé pour déterminer la hauteur de la cellule après le processus de dimensionnement automatique. Vous devrez arrondir la hauteur avec la fonction ceil (). J'ai également ajouté un facteur de fudge supplémentaire.

Le dernier bit de code est la façon dont vous configurez le texte pour la cellule. Pour cet exemple, simplement:

func configureCell(cell :UITableViewCell, atIndexPath indexPath: NSIndexPath) {
    if let realCell = cell as? MarkerFeltCell  {
        realCell.configureCellWithString("Multi-line string.\nLine 2.\nLine 3.")    // Use \n to separate lines
    }
}

Aussi, voici un coup de feu de la plume. A épinglé l'étiquette aux bords de la cellule (avec la marge souhaitée), mais a utilisé une contrainte "Supérieur ou égal à", avec une priorité inférieure à "Required" pour la contrainte inférieure.

Cell constraints

Définissez la police de l'étiquette sur Attribué. La police IB réelle n'avait pas d'importance.

LabelFont

Le résultat dans ce cas:

CellResults

0
anorskdev