Пользовательский установленный шрифт неправильно отображается в UILabel


83

Я пытаюсь использовать шрифт Helvetica Neue Condensed, который я получил из пакета Adobe Font Collection Pro Package. К сожалению, он отображается неправильно, когда я использую его в UILabel.

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

Снимок экрана с неправильным рендерингом шрифта

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

Что могло быть не так с файлом шрифта или моим кодом, из-за которого он рисовался таким образом?


Могу ли я как-нибудь создать подкласс UIFont, который может исправить эти проблемы?
MikeQ

+1 - у меня такая же проблема. Я пробовал использовать ZFont, чтобы помочь с этим, и это действительно помогает, но недостаточно. Возможно, что-то не так с тем, как интерлиньяж интерпретируется с помощью этих пользовательских шрифтов (на самом деле, понятия не имею, но я должен думать, что это может иметь какое-то отношение к этому!).
Joe D'Andrea

Привет! Вы в конце концов нашли решение? Пожалуйста, ответьте на ваш вопрос, если да. Заранее спасибо.
Soonts

К сожалению, нет. И у меня больше нет доступа к исходному файлу шрифта, который вызвал эту проблему. Мне нравится ответ Колючего .. Я только хотел бы проверить его в моем конкретном случае.
MikeQ

Просто чтобы вы знали, это было исправлено в iOS7.
Чувак

Ответы:


125

Я опубликовал решение, которое включает исправление файла шрифта ttf здесь :

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

1
Вы также можете попробовать Mensis или FontForge. Эти приложения также можно использовать для изменения свойства восходящего элемента.
колючий

1
Вы сделали мой день. Я застрял с этой проблемой несколько недель. Могу пользоваться довольно часто!
TheBeardedCoda

1
Обратите внимание, что при увеличении восходящего элемента вы увеличиваете межстрочный интервал - это может быть проблемой, если в вашем приложении есть многострочный текст.
Павел Алексеев

2
** ПОЖАЛУЙСТА, СМОТРИТЕ ТАКЖЕ ОТВЕТ ДЖОЗЕФА ЛИНА НИЖЕ ** Вы должны отрегулировать верхний элемент и установить нулевой интервал, чтобы обеспечить хорошее выравнивание как на iOS 6, так и на iOS 7!
Ken M. Haggerty

64

Итак, это модифицированная версия ответа Колючего .

Я открыл свой шрифт с помощью Glyphs , а затем экспортировал его, ничего не меняя. Каким-то волшебным образом проблема с вертикальным выравниванием исчезла!

Что лучше, так это то, что новый шрифт прекрасно сочетается с такими методами, как sizeWithFont:, например , и не имеет проблем, упомянутых Джошуа .

Я взглянул на таблицу HHEA с упомянутой командой kolyuchiy и заметил, что Glyphs модифицировали не только the 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, и он работает как на iOS 6, так и на iOS 7.
phatmann

Да. Уменьшение lineGap до нуля (0) и оставление восходящего элемента (в 1991 г.) решило для меня проблему с бесплатным шрифтом Overpass из Fedora. Спасибо всем за руководство к решению. Работает как на iOS6, так и на iOS7.
Стивенхаузер

Я только что пришел к такому же выводу, что и @phatmann, после нескольких неудачных попыток с Glyphs и OS X Font Tools. Дело в том, что лучше использовать этот трюк с OS X Font Tools вместо простого экспорта с помощью Glyphs, потому что Glyphs также редактирует имя стиля шрифта и имя postscript, что в некоторых ситуациях заставляет xCode не находить шрифт.
huong

32

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

Решение состоит в том, чтобы сделать lineGap 0 и соответственно увеличить зажим для зажима. За ответ выше , одним из решений является импорт и экспорт из Glyphs. Однако обратите внимание, что будущая версия приложения может исправить эту «ошибку».

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

  1. Установите OS X Font Tools.
  2. Выгрузите метрики шрифта в файл: ftxdumperfuser -t hhea -A d YOUR_FONT.ttf
  3. Откройте выгруженный файл в редакторе.
  4. Отредактируйте ascenderсвойство, добавив к нему значение lineGapсвойства. Например, если lineGapэто 200 и ascender750, сделайтеascender 950.
  5. Установить lineGap значение 0.
  6. Сливаем изменения в шрифт: ftxdumperfuser -t hhea -A f YOUR_FONT.ttf

Как только вы это сделаете, вам, возможно, придется соответствующим образом настроить свой пользовательский интерфейс.


4

У нас была такая же проблема с одним из наших пользовательских шрифтов. Мы также «исправили» проблему, отредактировав свойство font ascender. Однако мы обнаружили, что это создало другие проблемы и проблемы с компоновкой. Например, динамическая установка высоты ячейки на основе высоты метки взорвется при использовании шрифта, отредактированного с помощью восходящего элемента.

В итоге мы изменили свойство UIButton contentEdgetInsets.

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

Не уверен, какой метод лучше, но просто хотел поделиться другим способом решения проблемы.


2
согласовано. Исправление свойства восходящего элемента - не идеальное решение
Макс МакЛауд,

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

4
  1. Загрузите и установите Apple Font Tools здесь: 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 и выберите «Элемент» в верхнем меню, затем перейдите в «Информация о шрифте»> «OS / 2»> «Метрики». Здесь вы хотите отредактировать значения HHEad Line Gap и HHead Ascent Offset.

После того, как вы внесете необходимые изменения, вы можете просто экспортировать шрифт в File> Generate Fonts и выбрать правильный формат шрифта.


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свойства в раскадровке, если вы не программируете свои метки).


1

Вы пробовали Core Text ? У меня были некоторые успехи в рендеринге пользовательских шрифтов через Core Text, но я не знаю, подойдет ли это к вашей ситуации.


1
Я могу подтвердить, что в основном тексте этой проблемы нет.
перелет


0

Если у вас возникли проблемы с этими утилитами командной строки, попробуйте fontcreator в окне. и измените шрифт assender в его меню настроек.


0

Для тех, кто изо всех сил пытается использовать ftxdumperfuser( колючий ответ) в Mac OS Mojave из-за ошибки command not found:

  • Загрузите пакет инструментов для шрифтов от 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
  • Инструменты командной строки теперь доступны в ~ / font-tools / FontCommandLineTools.pkg / Payload, вы можете добавить папку в свой путь ( export PATH="$PATH:$HOME/font-tools/FontCommandLineTools.pkg/Payload") или скопировать утилиты в папку bin.

-3

У меня была аналогичная проблема с культовым шрифтом «FontAwesome» в моей игре Sprite Kit. Установка для свойства SKLabelNode SKLabelVerticalAlignmentMode значения .Center сработала для меня.

myLabel.verticalAlignmentMode = SKLabelVerticalAlignmentMode.Center

Просто хотел поделиться на случай, если кто-то будет бороться с той же проблемой.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.