Встановлений на замовлення шрифт неправильно відображається в UILabel


83

Я намагаюся використовувати шрифт Helvetica Neue Condensed, який я отримав із пакета Adobe Font Collection Pro. На жаль, здається, малюється неправильно, коли я використовую його в UILabel.

Здається, висота рядка розрахована правильно (я думаю), але коли шрифт відображається, він вирівнюється до самого верху обмежувального вікна. Я зателефонував [myLabel sizeToFit]і лише відрегулював ширину, щоб зробити цей знімок екрана:

Знімок екрана неправильного візуалізації шрифту

У мене була однакова проблема як із напівжирним шрифтом, так і зі звичайною версією шрифту. Я зміг витягнути версію Helvetica Neue Bold з OSX і поставити її на свій пристрій, і вона відображається чудово (зелений фон на малюнку вище).

Що може бути не так із файлом шрифту або моїм кодом, що спричинить його малювання таким чином?


Чи можу я якось зробити підклас UIFont, який може виправити ці проблеми?
MikeQ

+1 - те саме для мене. Я намагався використовувати ZFont, щоб допомогти з цим, і це допомагає дещо, але недостатньо. Може бути щось недобре в тому, як інтерпретується провідний текст із тими нестандартними шрифтами (насправді немає підказки - але я повинен думати, що це може мати до цього щось спільне!).
Джо Д'Андреа,

Привіт! Ви врешті знайшли рішення? Будь ласка, дайте відповідь на своє запитання, якщо так. Заздалегідь спасибі.
Soonts

На жаль, ні, я не зробив. І я вже не маю доступу до оригінального файлу шрифту, який спричинив цю проблему. Мені подобається відповідь колючого. Я хотів би лише перевірити її у своєму конкретному випадку.
MikeQ

Щоб ви знали, це виправлено в iOS7.
Чувак,

Відповіді:


125

Я опублікував рішення, яке передбачає виправлення файлу шрифту ttf тут :

Ось рішення, яке працювало для мого користувальницького шрифту, який мав ту саму проблему в UILabel, UIButton тощо. Проблемою зі шрифтом виявився той факт, що властивість його ascender була замалою порівняно зі значенням системних шрифтів. Ascender - вертикальний пробіл над символами шрифту. Щоб виправити шрифт, вам доведеться завантажити утиліти командного рядка Apple Font Tool Suite . Потім візьміть шрифт і виконайте наступне:

~$ ftxdumperfuser -t hhea -A d Bold.ttf

Це створить Bold.hhea.xml. Відкрийте його за допомогою текстового редактора та збільште значення ascenderатрибута. Вам доведеться трохи поекспериментувати, щоб з’ясувати саме значення, яке найкраще вам підходить. У моєму випадку я змінив його з 750 на 1200. Потім знову запустіть утиліту за допомогою наступного командного рядка, щоб об’єднати ваші зміни назад у файл ttf:

~$ ftxdumperfuser -t hhea -A f Bold.ttf

Тоді просто використовуйте отриманий шрифт ttf у своєму додатку.


Велике спасибі, що запропонували цей інструмент! його також можна використовувати для перейменування шрифту, також редагуючи розділ "-t name".
Філіпп

1
Ви також можете спробувати Mensis або FontForge. Ці програми також можна використовувати для зміни властивості ascender.
колючий

1
Ти мене вразив. Я застряг у цій проблемі кілька тижнів. Я можу використовувати його досить часто!
TheBeardedCoda

1
Зверніть увагу, що за рахунок збільшення ascender ви збільшите міжрядковий інтервал - це може бути проблемою, якщо у вашому додатку є багаторядковий текст.
Павло Алексєєв

2
** БУДЬ ЛАСКА, ТАКОЖ ДИВІТЬСЯ ВІДПОВІДЬ ДЖОСЕФА ЛІНА ** Вам слід відрегулювати як підйом, так і встановити зазор на нуль, щоб забезпечити гарне вирівнювання як на iOS 6, так і на iOS 7!
Ken M. Haggerty

64

Отже, це модифікована версія відповіді колючого .

Я відкрив свій шрифт за допомогою Glyphs , а потім експортував його, нічого не змінюючи. Якось чарівно проблема з вертикальним вирівнюванням зникла!

Що краще, це те, що новий шрифт добре грає з такими методами, як sizeWithFont:, отже, у нього немає проблем, згаданих Джошуа .

Я подивився таблицю HHEA із згаданою командою колючий і помітив, що Glyphs модифікував не лише те ascender, але lineGapі numberOfHMetricsдля мене.

Ось вихідні дані, раніше:

versionMajor="1"
versionMinor="0"
ascender="780"
descender="-220"
lineGap="200"
advanceWidthMax="1371"
minLeftSideBearing="-73"
minRightSideBearing="-52"
xMaxExtent="1343"
caretSlopeRise="1"
caretSlopeRun="0"
caretOffset="0"
metricDataFormat="0"
numberOfHMetrics="751"

і після:

versionMajor="1"
versionMinor="0"
ascender="980"
descender="-220"
lineGap="0"
advanceWidthMax="1371"
minLeftSideBearing="-73"
minRightSideBearing="-52"
xMaxExtent="1343"
caretSlopeRise="1"
caretSlopeRun="0"
caretOffset="0"
metricDataFormat="0"
numberOfHMetrics="748"

Тож мораль історії - не просто збільшуйте підйом, але й модифікуйте інші пов’язані цінності.

Я не фахівець із типографіки, тому не можу насправді пояснити, чому і як. Якщо хтось може надати кращі пояснення, це буде вдячне! :)


Після збереження TTF, який я використовую знову, використовуючи Glyphs, шрифт поводиться майже однаково на iOS 6 та iOS 7. Раніше його
вихідна

6
Дякуємо, що нарешті зрозуміли це! Очевидно, iOS 6 відзначає властивість lineGap, тоді як iOS 7 ігнорує його. Рішення полягає в тому, щоб зробити lineGap 0 і збільшити піднімаючий відповідно. Це саме те, що зробили
Glyphs

Так. Зменшення lineGap до нуля (0) і залишення піднімається (на 1991 рік) вирішили проблему для мене за допомогою безкоштовного шрифту "Overpass" від Fedora. Дякую усім за вказівки щодо рішення. Працює як на iOS6, так і на iOS7.
stephenhouser

Я щойно прийшов до того ж висновку, що і @ phatmann, після декількох невдалих спроб із Glyphs та OS X Font Tools. Справа в тому, що краще використовувати цей фокус із інструментами шрифтів OS X, а не просто експортувати за допомогою Glyphs, оскільки Glyphs також редагує ім'я стилю шрифту та ім'я постскриптума, завдяки чому xCode не вдається знайти шрифт у деяких ситуаціях.
huong

32

iOS 6 відзначає властивість lineGap шрифту, тоді як iOS 7 ігнорує його. Отже, лише користувацькі шрифти з пробілом у рядку 0 працюватимуть коректно в обох операційних системах.

Рішення полягає в тому, щоб зробити lineGap 0 і збільшити піднімаючий відповідно. Відповідно до наведеної вище відповіді , одним із рішень є імпорт та експорт із гліфів. Однак зверніть увагу, що майбутня версія програми може виправити цю "помилку".

Більш надійним рішенням є редагування шрифту самостійно відповідно до цієї публікації . Зокрема,

  1. Встановіть інструменти шрифтів OS X.
  2. Звантажити метрики шрифтів у файл: ftxdumperfuser -t hhea -A d YOUR_FONT.ttf
  3. Відкрийте звантажений файл у редакторі.
  4. Відредагуйте ascenderвластивість, додавши до нього вартість lineGapвластивості. Наприклад, якщо lineGapдорівнює 200, а ascenderдорівнює 750, зробіть ascender950.
  5. Встановіть значення lineGap0.
  6. Об’єднайте зміни у шрифт: ftxdumperfuser -t hhea -A f YOUR_FONT.ttf

Після цього вам, можливо, доведеться відповідним чином відрегулювати свій інтерфейс.


4

У нас була та ж проблема з одним із наших спеціальних шрифтів. Ми також "усунули" проблему, відредагувавши властивість font ascender. Однак ми виявили, що це створило інші проблеми та проблеми з макетом. Наприклад, динамічне встановлення висоти комірки на основі висоти етикетки підірветься при використанні нашого редагованого шрифту.

У підсумку ми змінили властивість UIButton contentEdgetInsets.

yourButton.contentEdgeInsets = UIEdgeInsetsMake(-10, 0, 0, 0);

Не впевнений, який метод кращий, але просто хотів поділитися іншим способом вирішення проблеми.


2
погодився. Виправлення властивості ascender не є ідеальним рішенням
Макс Маклауд,

1
Привіт Джошуа, я щойно опублікував метод, який може вирішити проблему, про яку ти згадав. Коротше кажучи, ще кілька властивостей потрібно змінити разом із підніманням.
Джозеф Лін

4
  1. Завантажте та встановіть інструменти шрифтів Apple тут: https://developer.apple.com/downloads/index.action?q=font (посилання для завантаження знаходиться внизу)
  2. Відкрийте термінал і пройдіть по дорозі туди, де знаходиться ваш шрифт
  3. Виконайте цю команду: ftxdumperfuser -t hhea -A d MY_FONT_NAME.ttf
  4. Тепер у вас є файл xml з деякими властивостями шрифту, відредагуйте його у своєму текстовому редакторі
  5. Знайдіть властивість "lineGap" і додайте 200 до його значення
  6. Збережіть файл xml
  7. Виконайте цю команду: ftxdumperfuser -t hhea -A f MY_FONT_NAME.ttf
  8. Видаліть файл xml
  9. Спробуйте налаштований шрифт на iOS 6 і перевірте, чи виглядає він краще.
  10. Якщо вам потрібно, ви можете повернутися до кроку 3 і додати / відняти до властивості "lineGap". (У підсумку я додав 250 до своєї конфігурації)

4

Для тих, хто працює під управлінням OS X El Capitan і приходить до цієї теми, ви могли помітити, що Apple Font Tool Suite більше не сумісний (принаймні на даний момент).

Але ви все ще можете виконати зміни, описані Колючим та Джозефом Ліном, за допомогою безкоштовного програмного забезпечення для редагування шрифтів FontForge .

Відкрийте шрифт за допомогою FontForge і виберіть Element у верхньому меню, а потім перейдіть до Font Info> OS / 2> Metrics. Там ви хочете відредагувати значення проміжку рядків HHEad та зміщення HHead Ascent.

Після того, як ви внесли необхідні редагування, ви можете просто експортувати шрифт у Файл> Створити шрифти та вибрати правильний формат шрифту


3

Завдяки цій відповіді я вирішив свою проблему з гліфами, але трохи інакше.

Я відкрив свій шрифт за допомогою Glyphs (також працює з Glyphs mini) і знайшов там цей розділ (це від Glyphs mini, щоб туди натиснути кнопку i у правому верхньому куті):

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

Просто видаліть усі ці зони вирівнювання (або деякі з них), і це вирішить цю проблему. У мене чудово працювало.


2

Створення атрибутивного тексту з тексту ваших міток було для мене виправленням. Ось розширення:

extension UILabel {
    /// You can call with or without param values; without will use default 2.0
    func setLineSpacing(lineSpacing: CGFloat = 2.0, lineHeightMultiple: CGFloat = 2.0) {
        guard let labelText = self.text else { return }
        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.lineSpacing = lineSpacing
        paragraphStyle.lineHeightMultiple = lineHeightMultiple
        let attributedString:NSMutableAttributedString
        if let labelattributedText = self.attributedText {
            attributedString = NSMutableAttributedString(attributedString: labelattributedText)
        } else {
            attributedString = NSMutableAttributedString(string: labelText)
        }
        // (Swift 4.2 and above) Line spacing attribute
        attributedString.addAttribute(NSAttributedString.Key.paragraphStyle, value:paragraphStyle, range:NSMakeRange(0, attributedString.length))
        self.attributedText = attributedString
    }
}

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

self.myLabel.setLineSpacing(lineSpacing: 1.2, lineHeightMultiple: 1.2)

Це працює, використовуючи рідне значення, NSMutableParagraphStyle()яке містить властивості висоти рядка та інтервалу (які також доступні як @IBOutletвластивості в Storyboard, якщо ви не програмуєте свої мітки).



1

Я використовував https://github.com/fonttools/fonttools - дуже простий у використанні та безкоштовний. У моєму випадку зміна 'ascender' = 1000 та 'lineGap' = 0 у таблиці 'hhea' зробила свою справу.

На основі статті Тревора Хармона https://medium.com/@thetrevorharmon/how-to-use-apples-font-tools-to-tweak-a-font-a386600255ae


0

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


0

Для тих, хто бореться із використанням ftxdumperfuser( количий відповідь) на Mac OS Mojave через помилку команди не знайдено:

  • Завантажте пакет інструментів шрифтів від Apple. Знайшов їх на https://developer.apple.com/download/more/?q=font , вибрав той для XCode 11.
  • Встановіть файл dmg
  • Введіть образ диска cd / Volumes / macOS \ Font \ Tools
  • Витягніть пакет у вибрану вами папку: pkgutil --expand-full macOS \ Font \ Tools.pkg ~ / font-tools
  • Інструменти CLI тепер доступні в ~ / font-tools / FontCommandLineTools.pkg / Payload, ви можете додати папку до свого шляху ( export PATH="$PATH:$HOME/font-tools/FontCommandLineTools.pkg/Payload") або скопіювати утиліти до вашої папки bin.

-3

У мене була подібна проблема зі знаковим шрифтом "FontAwesome" у моїй грі Sprite Kit. Встановлення властивості SKLabelVerticalAlignmentMode SKLabelNode в .Center спрацювало для мене.

myLabel.verticalAlignmentMode = SKLabelVerticalAlignmentMode.Center

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

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