web-dev-qa-db-ja.com

ストーリーボードのカスタムフォントを含む属性付きの文字列が正しく読み込まれない

プロジェクトではカスタムフォントを使用しています。 Xcode 5ではうまく機能します。Xcode6では、プレーンテキスト、コード内の属性付き文字列で機能します。ただし、ストーリーボードで設定されたこれらの文字列は、シミュレーターまたはデバイスで実行すると、すべてヘルベチカに戻りますが、ストーリーボードでは正常に見えます。

Xcode 6のバグなのか、iOS 8 SDKのバグなのか、Xcode 6/iOS 8でカスタムフォントの使用方法が変更されたのかはわかりません。

96
Allen Hsu

私にとっての修正は、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
    }
}

Interface Builderでこれを与える:

Interface Builder custom font with attributed string

通常と同じように属性付き文字列を設定できますが、利用可能な新しいプロパティでfontsizeとfontfamilyをもう一度設定する必要があります。

Interface Builderはデフォルトでカスタムフォントを使用しているため、結果として結果が得られます。これはアプリを作成するときに好みます。

プレーンバージョンの代わりにこれを使用しているのは、プレーンスタイルを使用する場合は使用できないlinespacingなどの属性ラベルにプロパティを設定しているためです。

30
Antoine

最も簡単な答えは、フォントをFontBookにドラッグすることです。フォントがプロジェクト内にあり、コンピューターのFontBook内にない場合、IBはそれを見つけるのに苦労することがあります。奇妙なことですが、私のために何度か働いてきました。

26
Alan Scarpa

フォントブックにカスタムフォントを追加できます。

Step1:フォントの管理をクリックします。フォントブックを開きます。

enter image description here

Step2:プラスをクリックしてフォントを追加します。

enter image description here

次回、属性付きテキストのフォントをクリックすると、新しく追加されたフォントもリストに表示されます。 しかし、カスタムフォントがinfo.plistとバンドルリソースに追加されていることを確認してください。

10

このスレッドのおかげで、私はこのソリューションに来ました:

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

私の解決策はちょっとした回避策です。実際の解決策は、AppleがInterface Builderを修正することです。

それを使用すると、システムフォントを使用してインターフェイスビルダーですべての太字と斜体のテキストをマークし、実行時にカスタムフォントをレンダリングできます。すべての場合に最適とは限りません。

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

この投稿 に触発された

4
KidA

同じ問題に遭遇しました。ストーリーボードのTextViewに設定された属性フォントは、XCode 6.1およびiOS 8 SDKで実行時に機能しませんでした。

これは私がこの問題を解決した方法です、あなたのための回避策かもしれません:

  1. テキストビューの属性インスペクターを開き、テキストを「プレーン」に変更します

  2. 「wC hR」(下の赤)を削除するには、十字をクリックします

    enter image description here

  3. テキストを「属性」に変更すると、テキストのフォントとサイズを設定できます。

  4. 動作するかどうかを確認するために実行します
3
Zhihao Yang

私はこのバグに苦労しました:UILabelはカスタムフォントでIBに正しく表示されますが、デバイスまたはシミュレーターに正しく表示されません(フォントはプロジェクトに含まれ、プレーンUILabelsで使用されます)。

最後に(Mac)App StoreでAttributed String Creatorを見つけました。アプリの適切な場所に配置するコードを生成します。素晴らしい。私はクリエーターではなく、ただの幸せなユーザーです。

3
ghr

同じ問題に遭遇しました。ストーリーボードのUILabelの属性フォントは実行時に機能しませんでした。このUIFont + IBCustomFonts.mを使用すると、私にとってはうまくいきます https://github.com/deni2s/IBCustomFonts

2
Praveen Sevta

@Hamidptbソリューションは機能します。フォントの正しい名前を取得してください(Font Bookに追加したら)

  • Font Bookアプリケーションを開き、フォントに移動してからCommand + Iを押します。 PostScript nameは、ここで使用するフォント名です。

    UILabel.appearance()。font = UIFont(name: "PostScriptName"、サイズ:17)

1
itsmcgh

ダブルクリックしてフォントをシステムにインストールします。動作します(Xcode 8.2)

1

同じ問題。

解決済み:TextViewでSelectableをチェックするだけです。これがなければ、標準のシステムフォントがあります。

1
Maselko

コード内の属性付き文字列にカスタムフォントを適用する場合:viewDidLayoutSubviewsで設定してみてください。私の間違いはviewDidLoadでそれをしていたので、そこでは適用されません。

0

属性付き文字列の場合は、フォントリストにカスタムフォントを追加できます-フォントアイコンをクリックすると、次のダイアログが表示されます。次のダイアログでは、カスタムフォント用に独自のカテゴリまたは既存のカテゴリを追加できます。 属性付きフォントダイアログ

Manage Fontsをクリックすると、次のダイアログが開きます。作成したカテゴリまたは既存のカテゴリを選択します。カテゴリにフォントを追加するには、+記号をクリックします。 フォントの管理ダイアログ

0
Sunil Singh

それはシンプルで素早い解決策であり、私の場合はうまくいきます。その解決策は、AppDelegate.SwiftファイルのdidFinishLaunchingWithOptions funcにコード行を追加することです。

textViewsの場合

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

ラベル用

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

そして、この2つのようなUiViewの残りのために☝️

0

複数の段落を持つテキストを含むtableViewセルを取得しようとしていました。属性付きの文字列は、段落間に余分なスペースを確保する方法のように見えました(文字列で2つの改行を行うよりも少し見栄えが良い)。セルに別のテキストを入れたいときに、実行時にIB設定が適用されないことを発見したときに、この投稿と他の投稿に出くわしました。

私が思いついた主なことは、特定の特性を持つ属性付き文字列を作成するために、文字列に拡張機能を追加することでした(Swiftを使用)。ここの例では、Helveticaと簡単に区別できるため、Marker Feltフォントを使用しています。また、この例では、段落をより明確にするために、段落間に少し余分なスペースを追加しています。

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

次に、カスタムtableViewCellで、必要なテキストを送信し、UILabelの属性付き文字列に変換します。

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

TableViewを備えたView Controllerで、viewDidLoad()にセルを登録する必要があります-私はnibを使用したので、次のようになります。

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

セルの高さを把握するには、サイズ情報を取得するために使用され、tableViewに追加されないプロトタイプセルを作成します。したがって、View Controllerの変数では:

var prototypeSummaryCell : MarkerFeltCell? = nil

次に、(おそらく、View Controllerに応じてオーバーライドします)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 {  // ...

上記のコードでは、prototypeCellは最初に必要なときに入力されます。次に、prototypeCellを使用して、自動サイズ調整プロセスを行った後のセルの高さを計算します。 ceil()関数で高さを切り上げる必要があります。ファッジファクターも追加しました。

最後のコードビットは、セルのテキストを構成する方法です。この例では、単純に:

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

また、ここにペン先のショットがあります。ラベルをセルの端に固定します(マージンは必要)が、下部の制約の優先度が「必須」未満の「より大きい」または「等しい」制約を使用しました。

Cell constraints

ラベルのフォントを属性付きに設定します。実際のIBフォントは関係ありません。

LabelFont

この場合の結果:

CellResults

0
anorskdev