首页 文章

故事板中包含自定义字体的归因字符串无法正确加载

提问于
浏览
91

我们在项目中使用自定义字体 . 它在Xcode 5中运行良好 . 在Xcode 6中,它以纯文本形式工作,在代码中归因于字符串 . 但是,在故事板中设置的那些归因字符串在模拟器或设备上运行时都会恢复到Helvetica,尽管它们在故事板中看起来很好 .

我不确定这是Xcode 6或iOS 8 SDK的错误,还是在Xcode 6 / iOS 8中改变了使用自定义字体的方式?

14 回答

  • 4

    我的修复是使用 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

    您可以像平常一样设置attributesstring,但是您必须在新的可用属性中再次设置fontsize和fontfamily .

    由于Interface Builder默认使用自定义字体,因此会产生您所看到的内容,我在构建应用时更喜欢这样 .

    Note

    我使用它而不是普通版本的原因是我在属性标签上设置属性,如linespacing,这在使用普通样式时是不可用的 .

  • 1

    最简单的答案是将字体拖到FontBook中 . 如果字体在您的项目中而不在您的计算机的FontBook中,则IB有时无法找到它 . 很奇怪,但曾多次为我工作过 .

  • 1

    您可以将自定义字体添加到字体簿 .

    Step1 :点击管理字体 . 它打开字体书 .

    enter image description here

    Step2 :单击加号并添加字体 .

    enter image description here

    下次单击带有属性文本的字体时,新添加的字体也将显示在列表中 . But make sure your custom font added in info.plist and bundle resources.

  • 29

    感谢这个帖子,我来到这个解决方案:

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

    我的解决方案是一个解决方案 . 真正的解决方案是让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;
    }
    

    灵感来自this post

  • 25

    遇到同样的问题:故事板中TextView的属性字体集在运行时与XCode 6.1和iOS 8 SDK无法一致 .

    这就是我解决这个问题的方法,可能是一种解决方法:

    • 打开textview的属性检查器,将文本更改为“Plain”

    • 点击十字架删除“wC hR”(下方红色)

    enter image description here

    • 将文本更改为“已归属”,然后您可以设置文本的字体和大小 .

    • 运行以检查它是否有效

  • 7

    遇到同样的问题:故事板中UILabel的属性字体在运行时不起作用 . 使用这个UIFont IBCustomFonts.m对我有用https://github.com/deni2s/IBCustomFonts

  • 0

    一样的问题 .

    解决:只需在TextView中选中Selectable即可 . 没有这个我有标准的系统字体 .

  • 2

    我一直在努力解决这个问题:UILabel在IB中使用自定义字体正确显示但在设备或模拟器上无法正确显示(字体包含在项目中并用于普通UILabels) .

    终于在(Mac)App Store上找到了Attributed String Creator . 生成要在适当位置放置在应用程序中的代码 . 太棒了 . 我不是创作者,只是一个快乐的用户 .

  • 1

    双击并将字体安装到系统 . 它会工作(Xcode 8.2)

  • 0

    我试图让tableView单元格的文本有多个段落 . 归因字符串似乎是在段落之间获得额外空间的一种方式(比在字符串中执行两个换行更好看) . 当我发现当你想在单元格中放入不同的文本时,IB设置不适用于运行时,遇到了这个和其他帖子 .

    我想到的主要是添加String的扩展(使用Swift)来创建具有某些特征的属性字符串 . 此处的示例使用Marker Felt字体,因为它很容易与Helvetica区分开来 . 该示例还显示段落之间的一点点间距,以使它们彼此更加不同 .

    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的视图控制器中,你应该在viewDidLoad()中注册你的单元格 - 我使用了一个nib,所以类似于:

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

    要让单元格确定它应该有多高,请创建一个用于获取大小信息的原型单元格,并且永远不会添加到tableView中 . 所以,在你的视图控制器的变量中:

    var prototypeSummaryCell : MarkerFeltCell? = nil
    

    然后in(可能覆盖 - 取决于您的视图控制器)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

    将标签的字体设置为Attributed . 实际的IB字体无关紧要 .

    LabelFont

    在这种情况下的结果:

    CellResults

  • 5

    如果是属性字符串,您可以在字体列表中添加自定义字体作为 - 单击字体图标,这将显示以下对话框 . 在以下对话框中,您可以添加自己的类别或现有字体用于自定义字体 . attributed font dialog

    单击“管理字体”后,打开以下对话框,选择您创建的或现有的类别 . 单击符号以在类别中添加字体 . Manage font dialog

  • 0

    这是一个简单快速的解决方案,这在我的案例中是有效的 . 该解决方案是在AppDelegate.swift文件中的didFinishLaunchingWithOptions func中添加代码行:

    for textViews

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

    for labels

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

    和UiView的其余部分一样,这两个☝️

  • 0

    @Hamidptb解决方案有效,请确保获得正确的字体名称(一旦将其添加到Font Book中)

    • 打开Font Book应用程序,导航到您的字体,然后按Command I. PostScript name是您要在此处使用的字体名称:

    UILabel.appearance() . font = UIFont(名称:“ PostScriptName ”,大小:17)

相关问题