Присвоєний рядок зі спеціальними шрифтами в дошці розкадрувань неправильно завантажується


100

Ми використовуємо власні шрифти у своєму проекті. Він добре працює в Xcode 5. У Xcode 6 він працює у простому тексті з атрибутивним рядком у коді. Але ці приписувані рядки, розміщені в раскадровці, повертаються до Helvetica під час роботи на тренажері чи пристрої, хоча вони виглядають все добре в раскадровці.

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


Тут же проблема. Хочеться дізнатися, що там.
obeattie

1
Наразі ми створили користувальницький UILabel, названий GLMarkdownLabel, і експортували деякі властивості за допомогою IBInspectable, потім встановили рядки розмітки в аркуші розкадровки та переклали рядки розмітки назад у віднесені рядки, коли прокинулися з ніби.
Аллен Хсу

Зараз це довгострокове рішення, сподіваємось, що Apple виправить цю помилку в наступній версії Xcode.
Аллен Хсу

Yikes, така суровина. Дякуємо, що повідомили нам, що це не окрема проблема. Чи є радари?
obeattie

1
Зрештою, наше вирішення повернулося до використання IBCustomFonts для наших приписуваних міток.
yonix

Відповіді:


30

Виправленням для мене було використання 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
    }
}

Надаємо вам це в Інтерфейс Builder:

Користувацький шрифт Interface Builder з атрибутивним рядком

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

Оскільки Builder інтерфейсу за замовчуванням працює зі спеціальним шрифтом, це призводить до того, що ви бачите - те, що ви отримуєте , що я віддаю перевагу під час створення програм.

Примітка

Причиною того, що я використовую це замість простої версії, є те, що я встановлюю властивості на атрибутивну мітку, наприклад, пробіл рядків, які недоступні при використанні простого стилю.


1
Ваше рішення підтримує лише одне сімейство шрифтів та розмір для мітки, то чому б просто не використовувати натомість простий текст?
Аллен Хсу

Так само ми @IBInspectableтимчасово використовуємо атрибути замість шрифту та розміру. У нас є markdownTextвластивість, тому що більшу частину часу ми використовуємо атрибутивний рядок для жирного або підкресленого тексту. Потім розберіть текст розмітки на віднесений рядок з інформацією про шрифт і розмір для простого тексту.
Аллен Хсу

@AllenHsu, ти маєш рацію. Не згадував про це, але я використовую атрибутивний пробіл рядків для своєї мітки. Offcourse, інакше ти просто використаєш звичайний стиль :)
Антуан

Добре, ми експортували також lineSpacing: p Я думаю, я би прийняв вашу відповідь, оскільки це насправді помилка в Xcode, і немає кращого рішення на даний момент. Зачекаємо наступної версії Xcode.
Аллен Хсу

2
Це не вийде, якщо я хочу
виділити

28

Найпростіша відповідь, над якою працювали, - це перетягнути шрифти у FontBook. Якщо шрифти є у вашому проекті, але не у FontBook вашого комп’ютера, у ІБ іноді виникають проблеми з його пошуку. Дивно, але кілька разів працював на мене.


17
Хоча це дозволить Xcode вибрати спеціальний шрифт, він насправді не працює. Під час виконання шрифт не буде використовуватися так, як ви очікували.
Даніель

На жаль, мені не вдалося придумати рішення. Найкраще, що я міг зробити, це зареєструвати помилку в Apple.
Даніель

Так, це виправлення. У мене була моя розкадровка, розроблена іншим розробником, оновлення SVN нормально, але ніколи не отримав шрифт в інтерфейсі. Шрифт знаходився в ресурсах, але не відображався в інтерфейсі пристрою / симулятора. Оскільки він використовує атрибутивний рядок, я повинен мати його у «Книзі шрифтів». Це вирішує проблему.
karim

Так. це допомагає мені вирішити ту саму проблему. Коли я додаю нестандартний шрифт у книгу шрифтів, речі працюють як шарм.
Сушант Ягтап

1
Хоча це рішення працює в деяких випадках, я також стикався з тією ж проблемою, що і @Daniel в тому ж проекті з тим же сімейством шрифтів. XCode потрібно вирішити цю проблему.
dey.shin

16

Ви можете додати спеціальні шрифти до книги шрифтів.

Крок 1. Клацніть на керування шрифтами. Це відкриває книгу шрифтів.

введіть тут опис зображення

Крок 2 : Клацніть на плюс і додайте свої шрифти.

введіть тут опис зображення

Наступного разу, коли ви натиснете на шрифт із атрибутивним текстом, щойно доданий шрифт також з’явиться у списку. Але переконайтеся, що ваш власний шрифт додано до ресурсів info.plist та групи.


Це зробити роботу в розкадруванні , але після запуску його не показують форматування
Ван

1
@ Ван форматування? Скажіть, будь ласка, більше? Коли це не працює?
mahbaleshwar hegde

Я повинен встановити текст, який відповідає сумішшю rgualr та жирного шрифту. Я використовував рішення вище, тому він працював в розкадруванні , але коли я запустити додаток етикетки з зазначенням Isnt шрифт застосовується замість цього він показує системний шрифт
Ван

Ви додали власні шрифти в info.plist? Після цього просто надрукуйте усі сімейства шрифтів
mahbaleshwar hegde

2
так. Я можу встановити спеціальний шрифт у всьому додатку у випадку простого тексту, мені потрібно встановити для атрибутованого тексту
Ван

5

Завдяки цій темі я прийшов до цього рішення:

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
}

1
Хороша ідея. Це справді неймовірно, що це зламається в Apple. Дивовижно.
Fattie

4

Моє рішення - трохи обробка. Справжнє рішення полягає в тому, щоб 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

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

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


3

Зустрілися з тією ж проблемою: набір шрифтів атрибутів для TextView у рекламній дошці не працював під час роботи з XCode 6.1 та iOS 8 SDK.

Ось як я вирішив це питання, можливо, для вас буде вирішуватися:

  1. відкрийте інспектор атрибутів свого перегляду тексту, змініть текст на "Звичайний"

  2. натисніть на хрест, щоб видалити "wC hR" (червоний нижче)

    введіть тут опис зображення

  3. змінити текст на "Віднесено", і тоді ви можете встановити шрифт і розмір тексту.

  4. запустіть, щоб перевірити, чи працює він

Здається, що за замовчуванням не wC hRвстановлено жодного властивості, ні UILabelні UITextView.
Аллен Хсу

за допомогою xcode 6, ти встановив інший тип ширини висоти, наприклад "Регулярна ширина | будь-яка висота", "Компактна ширина | Регулярна висота"? оскільки у мене є проект, розроблений в Xcode 5, і його атрибутивне перегляд тексту працює навіть з iOS 8 SDK, я перевірив там налаштування і виявив, що різниця полягає лише в тому, що Xcode 6 дозволяє користувачам встановлювати шрифт для різних розмірів пристроїв, якщо ви встановлюєте текст у "Рівнина". Ця нова конфігурація може бути причиною того, що встановлення тексту "приписано", але шрифт не працює.
Чжіхао Ян

1
Ви використовуєте власні шрифти? Я маю на увазі самостійно вбудовані, а не системні шрифти.
Аллен Хсу

Ага, я подумав, що "Спеціальні" шрифти, які ви згадали, - це ті, які пропонує Xcode, якщо в ньому є шрифт "System".
Чжихао Ян

Це не працює для мене. Він працює для звичайного рядка, але не для атрибутивного рядка.
Пратік Сомая


2

Спробуйте це спрацює

У моєму випадку, коли я намагаюся встановити "Silversky Technology" як атрибутивний текст для мітки від конструктора інтерфейсів, він не відображається, коли я запускаю в тренажері, але показує в програмі інтерфейсу. Тому я використав один трюк, і я зробив шрифт Silversky на 1 піксель більший за текст технології.

Текст атрибутів має випуск шрифту однакового розміру, тому змініть розмір 1 слова, ця справа працює зі мною.

Можливо, це помилка xcode, але ця хитрість працює для мене.


1

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

Вирішено: Просто перевірте пункт "Вибір" у TextView. Без цього у мене є стандартний шрифт системи.



1

@Hamidptb працює, переконайтеся, що ви отримаєте правильну назву шрифту (як тільки ви додасте його до книги шрифтів)

  • Відкрийте додаток Font Book, перейдіть до свого шрифту та натисніть Command + I. Ім'я PostScript - це ім'я шрифту, яке ви хочете використовувати тут:

    UILabel.appearance (). Font = UIFont (назва: " PostScriptName ", розмір: 17)


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

Потім у моїй користувальницькій таблиціViewCell ви надсилаєте йому потрібний текст, і він перетворює його в атрибутивну рядок на UILabel.

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

У контролері перегляду з tableView слід зареєструвати свою комірку в viewDidLoad () - я використав ручку, так що:

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

Щоб клітина зрозуміла, наскільки вона повинна бути високою, зробіть прототип клітинки, яка використовується для отримання інформації про розмір, і ніколи не додається в tableView. Отже, у змінному контролері вашого перегляду:

var prototypeSummaryCell : MarkerFeltCell? = nil

Потім у (можливо, переосмислення - залежно від контролера перегляду) висотаForForWAtIndexPath:

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 буде заповнений в перший раз, коли це потрібно. Потім 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
    }
}

Також тут зроблений знімок голівки. Прикріпив мітку до країв комірки (з бажаним запасом), але використовував обмеження "Більше або рівне", з нижчим обмеженням, ніж "Необхідний".

Обмеження клітин

Встановіть шрифт мітки на Атрибутивний. Фактичний шрифт IB не мав значення.

LabelFont

Результат у цьому випадку:

CellResults


0

У випадку з атрибутивним рядком ви можете додати спеціальний шрифт у список шрифтів як - Клацніть на піктограмі шрифту, це відобразиться наступне діалогове вікно. У наступному діалоговому вікні ви можете додати власну категорію або існуючу для власного шрифту. діалогове вікно приписаного шрифту

Після натискання кнопки Керування шрифтами відкриється наступна діалогова категорія вибору у створеній або існуючій. Клацніть на + знак, щоб додати шрифт у категорії. Керування діалоговим вікном шрифту


0

це просте і швидке рішення, і це працює в моєму випадку. це рішення - додати рядок коду у функцію didFinishLaunchingWithOptions у файл AppDelegate.swift:

для textViews :

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

для міток :

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

і для решти UiView, як це два ☝️


0

Для всіх, хто застосовує власні шрифти до атрибутивного рядка в коді: Спробуйте встановити його viewDidLayoutSubviews. Моя помилка була в цьому viewDidLoad, вона не буде застосована там.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.