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?

MikeQ
źródło
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.

kolyuchiy
źródło
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! :)

Joseph Lin
źródło
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.

phatmann
źródło
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.

Joshua Dance
źródło
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)
nurnachman
źródło
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

Naiko
źródło
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.

DevilPinky
źródło
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).

App Dev Guy
źródło
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.

RyanR
źródło
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ń.

Gaurav
źródło
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.
Arnoldas Liudžius
źródło
-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.

Requig
źródło