Niestandardowa zainstalowana czcionka nie jest poprawnie wyświetlana w UILabel


83

Próbuję użyć czcionki Helvetica Neue Condensed, którą otrzymałem z pakietu Adobe Font Collection Pro. Niestety wydaje się, że rysuje nieprawidłowo, gdy używam go w ramach UILabel.

Wydaje się, że wysokość linii jest obliczona poprawnie (tak mi się wydaje), ale kiedy czcionka jest wyświetlana, jest wyrównana do samej góry obwiedni. Zadzwoniłem [myLabel sizeToFit]i dostosowałem tylko szerokość, aby wykonać ten zrzut ekranu:

Zrzut ekranu przedstawiający nieprawidłowe renderowanie czcionek

Miałem ten sam problem zarówno z pogrubioną, jak i zwykłą wersją czcionki. Udało mi się pobrać wersję Helvetica Neue Bold z OSX i umieścić ją na moim urządzeniu i wyświetla się dobrze (zielone tło na powyższym obrazku).

Co może być nie tak z plikiem czcionki lub moim kodem, co mogłoby spowodować, że rysuje się w ten sposób?


Czy mógłbym jakoś stworzyć podklasę UIFont, która może naprawić te problemy?
— MikeQ,

+1 - dla mnie ten sam problem. Próbowałem użyć ZFont, aby w tym pomóc, i trochę pomaga, ale nie wystarczająco. Może być coś nie tak ze sposobem interpretacji wiodących czcionek w tych niestandardowych czcionkach (tak naprawdę nie ma pojęcia - ale muszę pomyśleć, że może to mieć z tym coś wspólnego!).
— Joe D'Andrea

Cześć! Czy w końcu znalazłeś rozwiązanie? Jeśli tak, odpowiedz na pytanie. Z góry dziękuję.
— Soonts

Niestety nie, nie zrobiłem tego. Nie mam już dawno dostępu do oryginalnego pliku czcionki, który spowodował ten problem. Podoba mi się odpowiedź kolyuchiy… Chciałbym tylko móc ją przetestować w moim konkretnym przypadku.
— MikeQ

Dla twojej wiadomości, zostało to naprawione w iOS7.
— Koleś

Odpowiedzi:


125

Opublikowałem rozwiązanie polegające na łataniu pliku czcionki ttf tutaj :

Oto rozwiązanie, które działało dla mojej niestandardowej czcionki, która miała ten sam problem w UILabel, UIButton i tym podobnych. Problem z czcionką polegał na tym, że jej właściwość wznosząca była zbyt mała w porównaniu z wartością czcionek systemowych. Ascender to pionowa spacja nad znakami czcionki. Aby naprawić czcionkę, musisz pobrać narzędzia wiersza poleceń Apple Font Tool Suite . Następnie weź czcionkę i wykonaj następujące czynności:

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

To stworzy Bold.hhea.xml. Otwórz go w edytorze tekstu i zwiększ wartość ascenderatrybutu. Będziesz musiał trochę poeksperymentować, aby znaleźć dokładną wartość, która będzie dla Ciebie najlepsza. W moim przypadku zmieniłem go z 750 na 1200. Następnie uruchom narzędzie ponownie, używając następującego wiersza poleceń, aby scalić zmiany z powrotem w pliku ttf:

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

Następnie po prostu użyj powstałej czcionki ttf w swojej aplikacji.


Wielkie dzięki za zasugerowanie tego narzędzia! można go również użyć do zmiany nazwy czcionki, edytując w podobny sposób sekcję „-t nazwa”.
— Philippe

1
Możesz także wypróbować Mensis lub FontForge. Te aplikacje mogą być również używane do zmiany właściwości wznoszenia.
— kolyuchiy

1
Uczyniłeś mój dzień. Utknąłem z tym problemem od kilku tygodni. Mogę go używać dość często!
— TheBeardedCoda

1
Zwróć uwagę, że zwiększając wznoszącą się, zwiększysz odstępy między wierszami - może to być problem, jeśli masz tekst wielowierszowy w swojej aplikacji.
— Pavel Alexeev,

2
** ZOBACZ TAKŻE ODPOWIEDŹ JOSEPHA LINA PONIŻEJ ** Powinieneś wyregulować zarówno wznoszący się, jak i ustawić linię zerową, aby zapewnić dobre wyrównanie zarówno w iOS 6, jak i iOS 7!
— Ken M. Haggerty

64

Więc to jest zmodyfikowana wersja odpowiedzi kolyuchiy .

Otworzyłem swoją czcionkę za pomocą Glyphs , a następnie wyeksportowałem ją bez modyfikowania czegokolwiek. W jakiś magiczny sposób zniknął problem z wyrównaniem w pionie!

Co lepsze, nowa czcionka ładnie współgra z metodami takimi jak sizeWithFont:, więc nie ma problemów, o których wspomniał Joshua .

Rzuciłem okiem na tabelę HHEA z poleceniem wspomnianym przez kolyuchiy i zauważyłem, że Glyphs modyfikowały nie tylko ascender, ale także lineGapi numberOfHMetricsdla mnie.

Oto nieprzetworzone dane, wcześniej:

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"

i po:

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"

A więc morał tej historii - nie tylko zwiększaj wznoszącą się, ale także modyfikuj inne powiązane wartości.

Nie jestem ekspertem w dziedzinie typografii, więc nie potrafię wyjaśnić, dlaczego i jak. Byłoby bardzo wdzięczne, gdyby ktokolwiek mógł podać lepsze wyjaśnienie! :)


Po zapisaniu TTF, którego używam ponownie przy użyciu Glifów, czcionka zachowuje się prawie tak samo na iOS 6 i iOS 7. Wcześniej jej linia bazowa byłaby źle wyrównana na iOS 6.
— leolobato

6
Dzięki za ostateczne rozwiązanie tego problemu! Najwyraźniej iOS 6 honoruje właściwość lineGap, podczas gdy iOS 7 ją ignoruje. Rozwiązaniem jest wykonanie lineGap 0 i odpowiednio powiększenie wyciągarki. To jest dokładnie to, co zrobiły Glyphs i działa zarówno na iOS 6, jak i iOS 7.
— phatmann

Tak. Zmniejszenie wartości lineGap do zera (0) i pozostawienie wznoszącej (1991) rozwiązało problem z darmową czcionką „Overpass” Fedory. Dziękuję wszystkim za wskazówki dotyczące rozwiązania. Działa na iOS6 i iOS7.
— stephenhouser

Właśnie doszedłem do tego samego wniosku, co @ phatmann's po kilku nieudanych próbach z użyciem Glyphs i OS X Font Tools. Chodzi o to, że lepiej jest użyć tej sztuczki z narzędziami czcionek OS X, zamiast po prostu eksportować z Glifami, ponieważ Glyphs edytuje również nazwę stylu czcionki i nazwę PostScript, co sprawia, że ​​xCode nie znajduje czcionki w niektórych sytuacjach.
— Huong

32

iOS 6 honoruje właściwość lineGap czcionki, podczas gdy iOS 7 ignoruje ją. Dlatego tylko niestandardowe czcionki z odstępem między wierszami równym 0 będą działać poprawnie w obu systemach operacyjnych.

Rozwiązaniem jest uczynienie lineGap 0 i odpowiednio powiększenie wyciągarki. Zgodnie z powyższą odpowiedzią , jednym z rozwiązań jest importowanie i eksportowanie z Glifów. Należy jednak pamiętać, że przyszła wersja aplikacji może naprawić ten „błąd”.

Bardziej niezawodnym rozwiązaniem jest samodzielna edycja czcionki, zgodnie z tym postem . Konkretnie,

  1. Zainstaluj narzędzia czcionek OS X.
  2. Zrzuć metryki czcionek do pliku: ftxdumperfuser -t hhea -A d YOUR_FONT.ttf
  3. Otwórz zrzucony plik w edytorze.
  4. Edytuj ascenderwłaściwość, dodając do niej wartość lineGapwłaściwości. Na przykład, jeśli lineGapwynosi 200, a ascenderwynosi 750, zrób ascender950.
  5. Ustaw na lineGap0.
  6. Scal zmiany w czcionce: ftxdumperfuser -t hhea -A f YOUR_FONT.ttf

Gdy to zrobisz, może być konieczne odpowiednie dostosowanie interfejsu użytkownika.


4

Mieliśmy ten sam problem z jedną z naszych niestandardowych czcionek. Rozwiązaliśmy również problem, edytując właściwość wznoszenia czcionki. Okazało się jednak, że spowodowało to inne problemy i problemy z układem. Na przykład dynamiczne ustawienie wysokości komórki na podstawie wysokości etykiety wydałoby się w górę, gdy użyjemy naszej edytowanej czcionki rosnącej.

Ostatecznie zmieniliśmy właściwość contentEdgetInsets UIButton.

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

Nie jestem pewien, która metoda jest lepsza, ale po prostu chciałem udostępnić inny sposób rozwiązania problemu.


2
Zgoda. Naprawa wzniesienia nie jest idealnym rozwiązaniem
— Max MacLeod

1
Cześć Joshua, właśnie opublikowałem metodę, która może rozwiązać problem, o którym wspomniałeś. Krótko mówiąc, wraz z wyciągarką trzeba zmodyfikować kilka innych właściwości.
— Joseph Lin

4
  1. Pobierz i zainstaluj narzędzia Apple Font Tools tutaj: https://developer.apple.com/downloads/index.action?q=font (łącze pobierania znajduje się na dole)
  2. Otwórz terminal i przejdź do miejsca, w którym znajduje się twoja czcionka
  3. Uruchom to polecenie: ftxdumperfuser -t hhea -A d NAZWA_MÓJ_CZCIONKI.ttf
  4. Teraz masz plik xml z niektórymi właściwościami czcionki, edytuj go w edytorze tekstu
  5. Wyszukaj właściwość „lineGap” i dodaj 200 do jej wartości
  6. Zapisz plik xml
  7. Uruchom to polecenie: ftxdumperfuser -t hhea -A f NAZWA_MÓJ_CZCIONKI.ttf
  8. Usuń plik xml
  9. Wypróbuj skonfigurowaną czcionkę na iOS 6 i zobacz, czy wygląda lepiej.
  10. Jeśli potrzebujesz, możesz wrócić do kroku 3 i dodać / odjąć do właściwości „lineGap”. (Skończyło się na dodaniu 250 do mojej konfiguracji)

4

Dla tych, którzy używają OS X El Capitan i przychodzą do tego wątku, mogliście zauważyć, że Apple Font Tool Suite nie jest już kompatybilny (przynajmniej na razie).

Ale nadal możesz wprowadzić zmiany opisane przez kolyuchiy i Josepha Lina za pomocą bezpłatnego oprogramowania do edycji czcionek FontForge .

Otwórz czcionkę za pomocą FontForge i wybierz Element w górnym menu, a następnie przejdź do Informacje o czcionce> OS / 2> Metryki. Tam chcesz edytować wartości HHEad Line Gap i HHead Ascent Offset.

Po dokonaniu niezbędnych zmian możesz po prostu wyeksportować czcionkę w Plik> Generuj czcionki i wybrać odpowiedni format czcionki


3

Dzięki tej odpowiedzi rozwiązałem swój problem z Glifami, ale trochę inaczej.

Otworzyłem swoją czcionkę za pomocą Glyphs (działa również z Glyphs mini) i znalazłem tam tę sekcję (ta z Glyphs mini, aby się tam dostać, naciśnij przycisk i w prawym górnym rogu):

wprowadź opis obrazu tutaj

Po prostu usuń wszystkie te strefy wyrównania (lub niektóre z nich), a to naprawi ten problem. U mnie zadziałało idealnie.


2

Tworzenie przypisanego tekstu z tekstu etykiet było dla mnie rozwiązaniem. Oto rozszerzenie:

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

W przypadku mojej niestandardowej czcionki otrzymałem wynik, którego potrzebuję z:

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

Działa to przy użyciu dostarczonego natywnego, NSMutableParagraphStyle()który zawiera właściwości wysokości linii i odstępów (które są również dostępne jako @IBOutletwłaściwości w Storyboard, jeśli nie programujesz etykiet).


1

Czy próbowałeś już Core Text ? Odniosłem pewne sukcesy podczas renderowania niestandardowych czcionek za pomocą Core Text, ale nie wiem, czy pasowałoby to do Twojej sytuacji.


1
Mogę potwierdzić, że podstawowy tekst nie ma tego problemu.
— przebijanie


0

Jeśli masz problemy z tymi narzędziami wiersza poleceń, wypróbuj fontcreator w oknie. i zmień czcionkę w menu ustawień.


0

Dla każdego, kto ma problemy z używaniem ftxdumperfuser( odpowiedź kolyuchiy ) w systemie Mac OS Mojave z powodu błędu polecenia nie znaleziono:

  • Pobierz pakiet narzędzi czcionek z Apple. Znalazłem je na https://developer.apple.com/download/more/?q=font , wybrałem ten dla XCode 11.
  • Zamontuj plik dmg
  • Wprowadź obraz dysku cd / Volumes / macOS \ Font \ Tools
  • Wypakuj pakiet do wybranego folderu: pkgutil --expand-full macOS \ Font \ Tools.pkg ~ / font-tools
  • Narzędzia CLI są teraz dostępne w ~ / font-tools / FontCommandLineTools.pkg / Payload, możesz dodać folder do swojej ścieżki ( export PATH="$PATH:$HOME/font-tools/FontCommandLineTools.pkg/Payload") lub skopiować narzędzia do folderu bin.

-3

Miałem podobny problem z kultową czcionką „FontAwesome” w mojej grze Sprite Kit. Ustawienie właściwości SKLabelNode SKLabelVerticalAlignmentMode na .Center zadziałało dla mnie.

myLabel.verticalAlignmentMode = SKLabelVerticalAlignmentMode.Center

Chciałem się tylko podzielić na wypadek, gdyby ktoś zmagał się z tym samym problemem.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.