Строка атрибута с пользовательскими шрифтами в раскадровке не загружается правильно

Мы используем пользовательские шрифты в нашем проекте. Он хорошо работает в Xcode 5. В Xcode 6 он работает в текстовом формате, присваивается строка в коде. Но те атрибутивные строки, которые установлены в раскадровке, все возвращаются к Helvetica при работе на симуляторе или устройстве, хотя они выглядят хорошо в раскадровке.

Я не уверен, что это ошибка Xcode 6 или iOS 8 SDK, или способ использования пользовательских шрифтов изменяется в Xcode 6/iOS 8?

Ответ 1

Исправление для меня заключалось в использовании класса 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 custom font with attributed string

Вы можете настроить свою атрибутированную строку так же, как вы это делаете, но вам придется снова установить свой шрифт и fontfamily в новых доступных свойствах.

По мере того, как интерфейс Builder работает с пользовательским шрифтом по умолчанию, это приводит к тому, что вы видите, что вы получаете, что я предпочитаю при создании приложений.

Примечание

Причина, по которой я использую это вместо простой версии, заключается в том, что я устанавливаю свойства на атрибутной метке, например, в строке, которые недоступны при использовании простого стиля.

Ответ 2

Самый простой ответ, который работал, - это перетащить шрифты в FontBook. Если шрифты находятся в вашем проекте, но не в вашем компьютере FontBook, у IB иногда возникают проблемы с его поиском. Странно, но работал у меня несколько раз.

Ответ 3

Вы можете добавить пользовательские шрифты в книгу шрифтов.

Шаг 1: Нажмите на управление шрифтами. Он открывает книгу шрифтов.

enter image description here

Шаг 2: Нажмите на плюс и добавьте ваши шрифты.

enter image description here

В следующий раз при нажатии на шрифт с атрибутивным текстом вновь добавленный шрифт также будет отображаться в списке. Но убедитесь, что ваш собственный шрифт добавлен в info.plist и пакет ресурсов.

Ответ 4

Благодаря этой теме я пришел к этому решению:

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

Мое решение - это немного работа. Реальное решение заключается в том, что Apple исправляет интерфейс 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;
}

Вдохновленный этот пост

Ответ 6

Встретил ту же проблему: шрифт атрибута, установленный для TextView в раскадровке, не работал во время выполнения с XCode 6.1 и iOS 8 SDK.

Вот как я решил эту проблему, может быть обходным путем для вас:

  • откройте инспектор атрибутов вашего текстового поля, измените текст на "Обычная"

  • нажмите на крест, чтобы удалить "wC hR" (красный ниже)

    enter image description here

  • измените текст на "Attributed", а затем вы можете установить шрифт и размер   для вашего текста.

  • запустить, чтобы проверить, работает ли он

Ответ 7

Я столкнулся с этой ошибкой: UILabel корректно отображается в IB с пользовательским шрифтом, но не отображается правильно на устройстве или симуляторе (шрифт включен в проект и используется в простых UILabels).

Наконец, нашел Attributed String Creator в (Mac) App Store. Создает код для размещения в вашем приложении в соответствующем месте. Фантастика. Я не создатель, просто счастливый пользователь.

Ответ 8

Встретил ту же проблему: шрифт атрибута для UILabel в раскадровке не работал во время выполнения. Использование этого UIFont + IBCustomFonts.m работает для меня https://github.com/deni2s/IBCustomFonts

Ответ 9

Та же проблема.

Решено: просто выберите Выбираемый в TextView. Без этого у меня есть стандартный системный шрифт.

Ответ 10

Дважды щелкните и установите шрифт в систему. Он будет работать (Xcode 8.2)

Ответ 11

Я пытался получить таблицы 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()
}}

В контроллере представления с табличным представлением вы должны зарегистрировать свою ячейку в viewDidLoad() - я использовал наконечник, поэтому что-то вроде:

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

Чтобы получить ячейку, чтобы выяснить, насколько она высока, сделайте ячейку прототипа, которая используется для получения информации о размере, и никогда не добавляется в таблицуView. Итак, в вашем просмотреть переменные контроллера:

var prototypeSummaryCell : MarkerFeltCell? = nil

Затем в (возможно, переопределить - в зависимости от вашего контроллера представления) 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 {  // ...

В приведенном выше коде прототипCell будет заполнен в первый раз, когда это необходимо. ПрототипCell затем используется для определения высоты ячейки после прохождения процесса автосохранения. Вам нужно округлить высоту с помощью функции 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

Ответ 12

В случае атрибутной строки вы можете добавить собственный шрифт в список шрифтов как - Нажмите на значок шрифта, который отобразит следующий диалог. В следующем диалоге вы можете добавить свою собственную категорию или существующую для пользовательского шрифта. атрибут шрифта

После этого нажмите "Управление шрифтами", чтобы открыть следующую категорию выбора диалога в созданном или существующем. Нажмите на знак +, чтобы добавить шрифт в категорию. Управление диалоговым окном шрифтов

Ответ 13

которые имеют простое и быстрое решение и которые работают в моем случае. это решение - добавить строку кода в функцию didFinishLaunchingWithOptions в файле AppDelegate.swift:

для textViews:

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

для этикеток:

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

и для остальных UiView, как это два ☝️

Ответ 14

Решение @Hamidptb работает, убедитесь, что вы получили правильное имя шрифта (как только вы добавили его в Font Book)

  • Откройте приложение Font Book, перейдите к шрифту и нажмите Ctrl + I. Имя PostScript - это имя шрифта, которое вы хотите использовать здесь:

    UILabel.appearance(). Font = UIFont (имя: " PostScriptName ", размер: 17)

Ответ 15

Для тех, кто применяет пользовательские шрифты к атрибутной строке в коде: попробуйте установить ее в viewDidLayoutSubviews. Моя ошибка заключалась в viewDidLoad, что я делал это в viewDidLoad, он там не применяется.