So verwenden Sie eine benutzerdefinierte Schriftart mit dynamischen Textgrößen in iOS7


87

In iOS7 gibt es neue APIs zum Abrufen einer Schriftart, die automatisch an die Textgröße angepasst wird, die der Benutzer in seinen Einstellungen festgelegt hat.

Es sieht ungefähr so ​​aus, um es zu benutzen:

UIFont *myFont = [UIFont fontWithDescriptor:[UIFontDescriptor preferredFontDescriptorWithTextStyle:UIFontTextStyleHeadline] size:0];

Unabhängig davon, welchem ​​Text Sie dies zuweisen, wird die Schriftgröße nach oben und unten verschoben, wenn der Benutzer die Einstellung der Systemtextgröße ändert. (Denken Sie daran, die zu hörenname:UIContentSizeCategoryDidChangeNotification Benachrichtigung und Ihre Ansicht zu aktualisieren, um die Größenänderung zu berücksichtigen.)

Wie verwende ich dynamischen Text mit einer anderen Schriftart als der Standard-Helvetica-Neue?


Ist es nicht Zeit für Sie, eine Antwort anzunehmen?
Khanh Nguyen

Ab ios-11 + unterstützt Apple die Verwendung benutzerdefinierter dynamischer Schriftgrößen. Zur Implementierung schauen Sie sich bitte diese Antwort an .
Umair Ali

Antworten:


132

Hinter den Kulissen dieser API verfügt Apple über eine Art Nachschlagetabelle, die eine bestimmte Schriftfamilie, Größe und manchmal symbolische Merkmale (wie Fettdruck) (z. B. UIFontTextStyleHeadline) und die vom Benutzer bevorzugte Textgröße zurückgibt. Letzteres ist eine Schnur, die sharedApplicationwie folgt abgezogen wurde :

[UIApplication sharedApplication].preferredContentSizeCategory;

(Ich habe alle Standardgrößen / Schriftarten / Merkmale für Helvetica-Neue für die verschiedenen dynamischen Textgrößen abgemeldet .) Seitdem haben wir die Handhabung für die Barrierefreiheitsgrößen hinzugefügt, was wichtig ist .

Alles, was Sie wirklich tun müssen, ist eine ähnliche Nachschlagetabelle zu erstellen. Unser Designer hat für mich eine einfache Tabelle erstellt:

Nachschlagetabelle für Schriftgröße

Beachten Sie, dass wir einige Stile hinzugefügt haben (Beschriftung 3 und 4), um 8 statt 6 zur Auswahl zu haben.

Dann möchten Sie es an einem geeigneten Ort platzieren, z. B. in einer Kategorie UIFontDescriptor . Sie möchten, dass Ihre Methode a zurückgibtUIFontDescriptor ähnliche API wie Apple zurückgibt, damit die Anpassung mit symbolischen Merkmalen usw. noch einfach ist.

Meine Kategorie sieht folgendermaßen aus:

UIFontDescriptor + AvenirNext.h

#import <UIKit/UIKit.h>

extern NSString *const ANUIFontTextStyleCaption3;

@interface UIFontDescriptor (AvenirNext)

+(UIFontDescriptor *)preferredAvenirNextFontDescriptorWithTextStyle:(NSString *)style;

@end

UIFontDescriptor + AvenirNext.m

#import "UIFontDescriptor+AvenirNext.h"

NSString *const ANUIFontTextStyleCaption3 = @"ANUIFontTextStyleCaption3";
NSString *const ANUIFontTextStyleCaption4 = @"ANUIFontTextStyleCaption4";

@implementation UIFontDescriptor (AvenirNext)
+(UIFontDescriptor *)preferredAvenirNextFontDescriptorWithTextStyle:(NSString *)style {
    static dispatch_once_t onceToken;
    static NSDictionary *fontSizeTable;
    dispatch_once(&onceToken, ^{
        fontSizeTable = @{
          UIFontTextStyleHeadline: @{
                                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: @26,
                                    UIContentSizeCategoryAccessibilityExtraExtraLarge: @25,
                                    UIContentSizeCategoryAccessibilityExtraLarge: @24,
                                    UIContentSizeCategoryAccessibilityLarge: @24,
                                    UIContentSizeCategoryAccessibilityMedium: @23,
                                    UIContentSizeCategoryExtraExtraExtraLarge: @23,
                                    UIContentSizeCategoryExtraExtraLarge: @22,
                                    UIContentSizeCategoryExtraLarge: @21,
                                    UIContentSizeCategoryLarge: @20,
                                    UIContentSizeCategoryMedium: @19,
                                    UIContentSizeCategorySmall: @18,
                                    UIContentSizeCategoryExtraSmall: @17,},

       UIFontTextStyleSubheadline: @{
                                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: @24,
                                    UIContentSizeCategoryAccessibilityExtraExtraLarge: @23,
                                    UIContentSizeCategoryAccessibilityExtraLarge: @22,
                                    UIContentSizeCategoryAccessibilityLarge: @22,
                                    UIContentSizeCategoryAccessibilityMedium: @21,
                                    UIContentSizeCategoryExtraExtraExtraLarge: @21,
                                    UIContentSizeCategoryExtraExtraLarge: @20,
                                    UIContentSizeCategoryExtraLarge: @19,
                                    UIContentSizeCategoryLarge: @18,
                                    UIContentSizeCategoryMedium: @17,
                                    UIContentSizeCategorySmall: @16,
                                    UIContentSizeCategoryExtraSmall: @15,},

              UIFontTextStyleBody: @{
                                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: @21,
                                    UIContentSizeCategoryAccessibilityExtraExtraLarge: @20,
                                    UIContentSizeCategoryAccessibilityExtraLarge: @19,
                                    UIContentSizeCategoryAccessibilityLarge: @19,
                                    UIContentSizeCategoryAccessibilityMedium: @18,
                                    UIContentSizeCategoryExtraExtraExtraLarge: @18,
                                    UIContentSizeCategoryExtraExtraLarge: @17,
                                    UIContentSizeCategoryExtraLarge: @16,
                                    UIContentSizeCategoryLarge: @15,
                                    UIContentSizeCategoryMedium: @14,
                                    UIContentSizeCategorySmall: @13,
                                    UIContentSizeCategoryExtraSmall: @12,},
          
          UIFontTextStyleCaption1: @{
                                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: @19,
                                    UIContentSizeCategoryAccessibilityExtraExtraLarge: @18,
                                    UIContentSizeCategoryAccessibilityExtraLarge: @17,
                                    UIContentSizeCategoryAccessibilityLarge: @17,
                                    UIContentSizeCategoryAccessibilityMedium: @16,
                                    UIContentSizeCategoryExtraExtraExtraLarge: @16,
                                    UIContentSizeCategoryExtraExtraLarge: @16,
                                    UIContentSizeCategoryExtraLarge: @15,
                                    UIContentSizeCategoryLarge: @14,
                                    UIContentSizeCategoryMedium: @13,
                                    UIContentSizeCategorySmall: @12,
                                    UIContentSizeCategoryExtraSmall: @12,},
          
          UIFontTextStyleCaption2: @{
                                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: @18,
                                    UIContentSizeCategoryAccessibilityExtraExtraLarge: @17,
                                    UIContentSizeCategoryAccessibilityExtraLarge: @16,
                                    UIContentSizeCategoryAccessibilityLarge: @16,
                                    UIContentSizeCategoryAccessibilityMedium: @15,
                                    UIContentSizeCategoryExtraExtraExtraLarge: @15,
                                    UIContentSizeCategoryExtraExtraLarge: @14,
                                    UIContentSizeCategoryExtraLarge: @14,
                                    UIContentSizeCategoryLarge: @13,
                                    UIContentSizeCategoryMedium: @12,
                                    UIContentSizeCategorySmall: @12,
                                    UIContentSizeCategoryExtraSmall: @11,},
          
        ANUIFontTextStyleCaption3: @{
                                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: @17,
                                    UIContentSizeCategoryAccessibilityExtraExtraLarge: @16,
                                    UIContentSizeCategoryAccessibilityExtraLarge: @15,
                                    UIContentSizeCategoryAccessibilityLarge: @15,
                                    UIContentSizeCategoryAccessibilityMedium: @14,
                                    UIContentSizeCategoryExtraExtraExtraLarge: @14,
                                    UIContentSizeCategoryExtraExtraLarge: @13,
                                    UIContentSizeCategoryExtraLarge: @12,
                                    UIContentSizeCategoryLarge: @12,
                                    UIContentSizeCategoryMedium: @12,
                                    UIContentSizeCategorySmall: @11,
                                    UIContentSizeCategoryExtraSmall: @10,},

          UIFontTextStyleFootnote: @{
                                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: @16,
                                    UIContentSizeCategoryAccessibilityExtraExtraLarge: @15,
                                    UIContentSizeCategoryAccessibilityExtraLarge: @14,
                                    UIContentSizeCategoryAccessibilityLarge: @14,
                                    UIContentSizeCategoryAccessibilityMedium: @13,
                                    UIContentSizeCategoryExtraExtraExtraLarge: @13,
                                    UIContentSizeCategoryExtraExtraLarge: @12,
                                    UIContentSizeCategoryExtraLarge: @12,
                                    UIContentSizeCategoryLarge: @11,
                                    UIContentSizeCategoryMedium: @11,
                                    UIContentSizeCategorySmall: @10,
                                    UIContentSizeCategoryExtraSmall: @10,},

          ANUIFontTextStyleCaption4: @{
                                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: @15,
                                    UIContentSizeCategoryAccessibilityExtraExtraLarge: @14,
                                    UIContentSizeCategoryAccessibilityExtraLarge: @13,
                                    UIContentSizeCategoryAccessibilityLarge: @13,
                                    UIContentSizeCategoryAccessibilityMedium: @12,
                                    UIContentSizeCategoryExtraExtraExtraLarge: @12,
                                    UIContentSizeCategoryExtraExtraLarge: @11,
                                    UIContentSizeCategoryExtraLarge: @11,
                                    UIContentSizeCategoryLarge: @10,
                                    UIContentSizeCategoryMedium: @10,
                                    UIContentSizeCategorySmall: @9,
                                    UIContentSizeCategoryExtraSmall: @9,},
        };
    });
    
    
    NSString *contentSize = [UIApplication sharedApplication].preferredContentSizeCategory;
    return [UIFontDescriptor fontDescriptorWithName:[self preferredFontName] size:((NSNumber *)fontSizeTable[style][contentSize]).floatValue];
}
+(UIFontDescriptor *)preferredAvenirNextDemiBoldFontDescriptorWithTextStyle:(NSString *)style {
    return [[self preferredAvenirNextFontDescriptorWithTextStyle:style] fontDescriptorWithSymbolicTraits:UIFontDescriptorTraitBold];
}

+(UIFontDescriptor *)preferredAvenirNextBoldFontDescriptorWithTextStyle:(NSString *)style {
    return [UIFontDescriptor fontDescriptorWithName:[self preferredBoldFontName] size:[self preferredAvenirNextFontDescriptorWithTextStyle:style].pointSize];
}

+(NSString *)preferredFontName {
    return @"AvenirNext-Medium";
}
+(NSString *)preferredBoldFontName {
    return @"AvenirNext-Bold";
}

@end

Wir haben uns dafür entschieden, dieselbe Basisschriftart AvenirNext-Mediumund dann Fettdruck und dergleichen über symbolische Merkmale zu verwenden, aber Sie könnten verrückt werden und verschiedene Gewichtsvarianten für Ihre Schriftart als Teil Ihrer Nachschlagetabelle angeben, wenn Sie möchtenAvenirNext-ExtraBold .

Das ist alles dazu! Wir benutzen es so:

[UIFont fontWithDescriptor:[UIFontDescriptor preferredAvenirNextFontDescriptorWithTextStyle:UIFontTextStyleHeadline] size: 0]

6
Ausgezeichnete Lösung, aber Sie fehlen die Zugänglichkeit Konstanten: UIContentSizeCategoryAccessibilityMedium, UIContentSizeCategoryAccessibilityLargeetc.
Ben Jackson

Ah interessant. Gut zu wissen, @BenJackson. Vielen Dank!
Bob Spryn

1
Warum nicht verlängern UIFont, damit Sie einfach verwenden können : [UIFont preferredAvenirFontForTextStyle:UIFontTextStyleHeadline]? Größe ist in dem Beispiel, das Sie unten geben, redundant?
Cleverbit

2
@richarddas einfach, um mit Apples Muster zu bleiben. Eine Größe von 0 wird ignoriert und durchläuft einfach die richtige Größe aus dem Deskriptor.
Bob Spryn

4
Ab iOS 8.4 hat Apple die Schriftgrößen ein wenig angepasst
Klaas

15

So mache ich das in Swift. Ich mag das, weil es allgemeiner ist, nur eine Tabelle benötigt und mit jeder Schriftart gut funktionieren sollte. Zuerst habe ich einen verallgemeinerten Multiplikator geschrieben (in einem Getter).

var fontSizeMultiplier : CGFloat {
    get {
        switch UIApplication.sharedApplication().preferredContentSizeCategory {
        case UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: return 23 / 16
        case UIContentSizeCategoryAccessibilityExtraExtraLarge: return 22 / 16
        case UIContentSizeCategoryAccessibilityExtraLarge: return 21 / 16
        case UIContentSizeCategoryAccessibilityLarge: return 20 / 16
        case UIContentSizeCategoryAccessibilityMedium: return 19 / 16
        case UIContentSizeCategoryExtraExtraExtraLarge: return 19 / 16
        case UIContentSizeCategoryExtraExtraLarge: return 18 / 16
        case UIContentSizeCategoryExtraLarge: return 17 / 16
        case UIContentSizeCategoryLarge: return 1.0
        case UIContentSizeCategoryMedium: return 15 / 16
        case UIContentSizeCategorySmall: return 14 / 16
        case UIContentSizeCategoryExtraSmall: return 13 / 16
        default: return 1.0
        }
    }
}

Dann aktualisiere ich die Schriftart (z. B. im Beobachter) UIFontDescriptorwie folgt:

textView.font = UIFont(descriptor: fontDescriptor!, size: fontDescriptor!.pointSize * fontSizeMultiplier)

Dies funktioniert nicht, da die pointSize jedes Mal exponentiell zunimmt, wenn Sie die Größe in den Einstellungen aktualisieren. Wenn Sie eine Standardschriftgröße festlegen, können Sie diese als Basis verwenden und diese mit dem fontSizeMultiplier multiplizieren.
TejAces

@ TejAces - Das funktioniert gut. Ich benutze es seit Jahren. Da es Literalwerte zurückgibt, sehe ich nicht, wie Sie denken, dass es zunehmen würde, wenn Sie die Einstellungen ändern.
Bill Weinman

12

In iOS 11 wurde die UIFontMetricsKlasse eingeführt. Erstellen Sie ein FontMetrics-Objekt für den gewünschten Textstil. Wählen Sie dann eine beliebige Schriftart aus, deren Größe der standardmäßigen dynamischen Schriftgröße entspricht. Anschließend können Sie das FontMetrics-Objekt bitten, diese Schriftart unter Berücksichtigung der aktuellen Einstellungen des Benutzers zu skalieren.

let bodyMetrics = UIFontMetrics(forTextStyle: .body)
let standardFont = ... // any font you want, for standard type size
let font = bodyMetrics.scaledFont(for: standardFont)

8

@ Bob Spryn Code schnell umgeschrieben:

import UIKit

extension UIFontDescriptor {

    private struct SubStruct {
        static var preferredFontName: NSString = "OEMeodedPashutPro-Regular"
    }

    class func preferredDescriptor(textStyle: NSString) -> UIFontDescriptor {
        struct Static {
            static var onceToken : dispatch_once_t = 0
            static var fontSizeTable : NSDictionary = NSDictionary()
        }

        dispatch_once(&Static.onceToken) {
            Static.fontSizeTable = [
                UIFontTextStyleHeadline: [
                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: 26,
                    UIContentSizeCategoryAccessibilityExtraExtraLarge: 25,
                    UIContentSizeCategoryAccessibilityExtraLarge: 24,
                    UIContentSizeCategoryAccessibilityLarge: 24,
                    UIContentSizeCategoryAccessibilityMedium: 23,
                    UIContentSizeCategoryExtraExtraExtraLarge: 23,
                    UIContentSizeCategoryExtraExtraLarge: 22,
                    UIContentSizeCategoryExtraLarge: 21,
                    UIContentSizeCategoryLarge: 20,
                    UIContentSizeCategoryMedium: 19,
                    UIContentSizeCategorySmall: 18,
                    UIContentSizeCategoryExtraSmall: 17
                ],
                UIFontTextStyleSubheadline: [
                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: 24,
                    UIContentSizeCategoryAccessibilityExtraExtraLarge: 23,
                    UIContentSizeCategoryAccessibilityExtraLarge: 22,
                    UIContentSizeCategoryAccessibilityLarge: 22,
                    UIContentSizeCategoryAccessibilityMedium: 21,
                    UIContentSizeCategoryExtraExtraExtraLarge: 21,
                    UIContentSizeCategoryExtraExtraLarge: 20,
                    UIContentSizeCategoryExtraLarge: 19,
                    UIContentSizeCategoryLarge: 18,
                    UIContentSizeCategoryMedium: 17,
                    UIContentSizeCategorySmall: 16,
                    UIContentSizeCategoryExtraSmall: 15
                ],
                UIFontTextStyleBody: [
                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: 21,
                    UIContentSizeCategoryAccessibilityExtraExtraLarge: 20,
                    UIContentSizeCategoryAccessibilityExtraLarge: 19,
                    UIContentSizeCategoryAccessibilityLarge: 19,
                    UIContentSizeCategoryAccessibilityMedium: 18,
                    UIContentSizeCategoryExtraExtraExtraLarge: 18,
                    UIContentSizeCategoryExtraExtraLarge: 17,
                    UIContentSizeCategoryExtraLarge: 16,
                    UIContentSizeCategoryLarge: 15,
                    UIContentSizeCategoryMedium: 14,
                    UIContentSizeCategorySmall: 13,
                    UIContentSizeCategoryExtraSmall: 12
                ],
                UIFontTextStyleCaption1: [
                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: 19,
                    UIContentSizeCategoryAccessibilityExtraExtraLarge: 18,
                    UIContentSizeCategoryAccessibilityExtraLarge: 17,
                    UIContentSizeCategoryAccessibilityLarge: 17,
                    UIContentSizeCategoryAccessibilityMedium: 16,
                    UIContentSizeCategoryExtraExtraExtraLarge: 16,
                    UIContentSizeCategoryExtraExtraLarge: 16,
                    UIContentSizeCategoryExtraLarge: 15,
                    UIContentSizeCategoryLarge: 14,
                    UIContentSizeCategoryMedium: 13,
                    UIContentSizeCategorySmall: 12,
                    UIContentSizeCategoryExtraSmall: 12
                ],
                UIFontTextStyleCaption2: [
                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: 18,
                    UIContentSizeCategoryAccessibilityExtraExtraLarge: 17,
                    UIContentSizeCategoryAccessibilityExtraLarge: 16,
                    UIContentSizeCategoryAccessibilityLarge: 16,
                    UIContentSizeCategoryAccessibilityMedium: 15,
                    UIContentSizeCategoryExtraExtraExtraLarge: 15,
                    UIContentSizeCategoryExtraExtraLarge: 14,
                    UIContentSizeCategoryExtraLarge: 14,
                    UIContentSizeCategoryLarge: 13,
                    UIContentSizeCategoryMedium: 12,
                    UIContentSizeCategorySmall: 12,
                    UIContentSizeCategoryExtraSmall: 11
                ],
                UIFontTextStyleFootnote: [
                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: 16,
                    UIContentSizeCategoryAccessibilityExtraExtraLarge: 15,
                    UIContentSizeCategoryAccessibilityExtraLarge: 14,
                    UIContentSizeCategoryAccessibilityLarge: 14,
                    UIContentSizeCategoryAccessibilityMedium: 13,
                    UIContentSizeCategoryExtraExtraExtraLarge: 13,
                    UIContentSizeCategoryExtraExtraLarge: 12,
                    UIContentSizeCategoryExtraLarge: 12,
                    UIContentSizeCategoryLarge: 11,
                    UIContentSizeCategoryMedium: 11,
                    UIContentSizeCategorySmall: 10,
                    UIContentSizeCategoryExtraSmall: 10
                ],
            ]
        }

        let contentSize = UIApplication.sharedApplication().preferredContentSizeCategory

        let style = Static.fontSizeTable[textStyle] as NSDictionary

        return UIFontDescriptor(name: SubStruct.preferredFontName, size: CGFloat((style[contentSize] as NSNumber).floatValue))
    }

}

Verwendung:

UIFont(descriptor: UIFontDescriptor.preferredDescriptor(UIFontTextStyleBody), size: 0)

1
Xcode 7.2 hat mich dazu gebracht, die letzten beiden Zeilen zu ändern: let style = Static.fontSizeTable[textStyle] as! NSDictionaryundreturn UIFontDescriptor(name: SubStruct.preferredFontName as String, size: CGFloat((style[contentSize] as! NSNumber).floatValue))
koen

Es wäre wirklich cool, wenn ich etwas tun könnte, das die bevorzugte Schriftart in Storyboard zeigt. Möglicherweise durch Unterklassen der Textelemente.
Aaron Bratcher

7

Versuche dies:

UIFontDescriptor *userHeadLineFont = [UIFontDescriptor preferredFontDescriptorWithTextStyle:UIFontTextStyleHeadline];
CGFloat userHeadLineFontSize = [userHeadLineFont pointSize];
myFont = [UIFont fontWithName:@"Baskerville" size:userHeadLineFontSize];

Beachten Sie jedoch, dass dieser Code nur eine Annäherung ist (Dynamic Type kann viel mehr als nur die Schriftgröße skalieren).


Können Sie die Paranthesis näher erläutern? Was mehr als die Skalierung sollte ich berücksichtigen?
Hfossli

2
Es gibt eine Zuordnung zwischen der Schriftart "dynamischer Typ" und der tatsächlich verwendeten Schriftart. Zum Beispiel kann kleine Schrift fett werden. Ich kenne die genaue Zuordnung nicht. Weitere Informationen finden Sie im letzten Bild ("optische Skalierung vom dynamischen Typ") in diesem Artikel: fireballed.org/linked/2013/07/08/ios-7-type .
Valfer

1
Dieser macht dasselbe wie die genehmigte richtige Antwort, aber ein bisschen Unterschied in der Anzahl der Zeilen. Tolle Lösung. Das gleiche in SWIFT stackoverflow.com/questions/35355695/…
Vanya

Hier ist ein funktionierender Link zu dem Artikel, den @valfer in den Kommentaren erwähnt hat: Beyond Helvetica: Die wahre Geschichte hinter Schriftarten in iOS 7
0xced

6

Ähnlich wie bei @ bill-weinman habe ich die Waage genommen und in eine Funktion aufgeteilt, die nicht auf einer bestimmten Schriftgröße von 16 basiert .

/// The font scale for a given font size.
///
/// - seealso: [Source](https://stackoverflow.com/a/33114525/3643020)
///
/// - Parameter fontSize: The font size.
/// - Returns: The font scale
public func fontScale(for fontSize: CGFloat) -> CGFloat {
    switch UIApplication.shared.preferredContentSizeCategory {
    case UIContentSizeCategory.accessibilityExtraExtraExtraLarge:    return (fontSize + 8) / fontSize
    case UIContentSizeCategory.accessibilityExtraExtraLarge:         return (fontSize + 7) / fontSize
    case UIContentSizeCategory.accessibilityExtraLarge:              return (fontSize + 6) / fontSize
    case UIContentSizeCategory.accessibilityLarge:                   return (fontSize + 5) / fontSize
    case UIContentSizeCategory.accessibilityMedium:                  return (fontSize + 4) / fontSize
    case UIContentSizeCategory.extraExtraExtraLarge:                 return (fontSize + 3) / fontSize
    case UIContentSizeCategory.extraExtraLarge:                      return (fontSize + 2) / fontSize
    case UIContentSizeCategory.extraLarge:                           return (fontSize + 1) / fontSize
    case UIContentSizeCategory.large:                                return 1.0
    case UIContentSizeCategory.medium:                               return (fontSize - 1) / fontSize
    case UIContentSizeCategory.small:                                return (fontSize - 2) / fontSize
    case UIContentSizeCategory.extraSmall:                           return (fontSize - 3) / fontSize
    default:
        return 1.0
    }
}

Es kann dann mit benutzerdefinierten Schriftarten wie diesen verwendet werden:

/// Light font of specified size.
///
/// - Parameter size: Font size.
/// - Returns: Light font of specified size.
func lightFont(ofSize size: CGFloat) -> UIFont {
    let scaledSize = size * fontScale(for: size)

    return UIFont(name: "HelveticaNeueLTStd-Lt", size: scaledSize)!
}

Dies ist nicht schlecht, wenn Sie sich in einem Stadium befinden, in dem Sie nicht alles fein abstimmen möchten. Auch wenn Ihre benutzerdefinierte Schriftart eher klein ist und standardmäßig skaliert werden muss.
JanBrinker

Zu Ihrer Information - mein Ansatz hängt nicht von der Schriftgröße ab. Es gibt einen Wert zurück, der auf einem Verhältnis basiert. Es funktioniert gut mit benutzerdefinierten / skalierten Schriftarten.
Bill Weinman

3

In iOS 11 können Sie Folgendes verwenden:

var customFont = UIFont.systemFont(ofSize: 17.0)
if #available(iOS 11.0, *) {
    customFont = UIFontMetrics.default.scaledFont(for: customFont)
}
// use customFont...

Siehe auch Erstellen von Apps mit dynamischem Typ WWDC 2017 - Sitzung 245 - iOS- Zeit 8:34.


2

Schneller 2.1-3.0-Code basierend auf @ smartDonkeys Port von @ Bob Spryn-Code. Auch mit den Apple-Größen von @Klaas aktualisiert .

import UIKit

extension UIFontDescriptor {

    private struct SubStruct {
        static var preferredFontName: String = "Roboto-Light"
    }

    class func preferredDescriptor(textStyle: NSString) -> UIFontDescriptor {
        struct Static {
            static var onceToken : dispatch_once_t = 0
            static var fontSizeTable : NSDictionary = NSDictionary()
        }

        dispatch_once(&Static.onceToken) {
            Static.fontSizeTable = [
                UIFontTextStyleHeadline: [
                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: 23,
                    UIContentSizeCategoryAccessibilityExtraExtraLarge: 23,
                    UIContentSizeCategoryAccessibilityExtraLarge: 23,
                    UIContentSizeCategoryAccessibilityLarge: 23,
                    UIContentSizeCategoryAccessibilityMedium: 23,
                    UIContentSizeCategoryExtraExtraExtraLarge: 23,
                    UIContentSizeCategoryExtraExtraLarge: 21,
                    UIContentSizeCategoryExtraLarge: 19,
                    UIContentSizeCategoryLarge: 17,
                    UIContentSizeCategoryMedium: 16,
                    UIContentSizeCategorySmall: 15,
                    UIContentSizeCategoryExtraSmall: 14
                ],
                UIFontTextStyleSubheadline: [
                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: 21,
                    UIContentSizeCategoryAccessibilityExtraExtraLarge: 21,
                    UIContentSizeCategoryAccessibilityExtraLarge: 21,
                    UIContentSizeCategoryAccessibilityLarge: 21,
                    UIContentSizeCategoryAccessibilityMedium: 21,
                    UIContentSizeCategoryExtraExtraExtraLarge: 21,
                    UIContentSizeCategoryExtraExtraLarge: 19,
                    UIContentSizeCategoryExtraLarge: 17,
                    UIContentSizeCategoryLarge: 15,
                    UIContentSizeCategoryMedium: 14,
                    UIContentSizeCategorySmall: 13,
                    UIContentSizeCategoryExtraSmall: 12
                ],
                UIFontTextStyleBody: [
                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: 53,
                    UIContentSizeCategoryAccessibilityExtraExtraLarge: 47,
                    UIContentSizeCategoryAccessibilityExtraLarge: 40,
                    UIContentSizeCategoryAccessibilityLarge: 33,
                    UIContentSizeCategoryAccessibilityMedium: 28,
                    UIContentSizeCategoryExtraExtraExtraLarge: 23,
                    UIContentSizeCategoryExtraExtraLarge: 21,
                    UIContentSizeCategoryExtraLarge: 19,
                    UIContentSizeCategoryLarge: 17,
                    UIContentSizeCategoryMedium: 16,
                    UIContentSizeCategorySmall: 15,
                    UIContentSizeCategoryExtraSmall: 14
                ],
                UIFontTextStyleCaption1: [
                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: 18,
                    UIContentSizeCategoryAccessibilityExtraExtraLarge: 18,
                    UIContentSizeCategoryAccessibilityExtraLarge: 18,
                    UIContentSizeCategoryAccessibilityLarge: 18,
                    UIContentSizeCategoryAccessibilityMedium: 18,
                    UIContentSizeCategoryExtraExtraExtraLarge: 18,
                    UIContentSizeCategoryExtraExtraLarge: 16,
                    UIContentSizeCategoryExtraLarge: 14,
                    UIContentSizeCategoryLarge: 12,
                    UIContentSizeCategoryMedium: 11,
                    UIContentSizeCategorySmall: 11,
                    UIContentSizeCategoryExtraSmall: 11
                ],
                UIFontTextStyleCaption2: [
                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: 17,
                    UIContentSizeCategoryAccessibilityExtraExtraLarge: 17,
                    UIContentSizeCategoryAccessibilityExtraLarge: 17,
                    UIContentSizeCategoryAccessibilityLarge: 17,
                    UIContentSizeCategoryAccessibilityMedium: 17,
                    UIContentSizeCategoryExtraExtraExtraLarge: 17,
                    UIContentSizeCategoryExtraExtraLarge: 15,
                    UIContentSizeCategoryExtraLarge: 13,
                    UIContentSizeCategoryLarge: 11,
                    UIContentSizeCategoryMedium: 11,
                    UIContentSizeCategorySmall: 11,
                    UIContentSizeCategoryExtraSmall: 11
                ],
                UIFontTextStyleFootnote: [
                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: 19,
                    UIContentSizeCategoryAccessibilityExtraExtraLarge: 19,
                    UIContentSizeCategoryAccessibilityExtraLarge: 19,
                    UIContentSizeCategoryAccessibilityLarge: 19,
                    UIContentSizeCategoryAccessibilityMedium: 19,
                    UIContentSizeCategoryExtraExtraExtraLarge: 19,
                    UIContentSizeCategoryExtraExtraLarge: 17,
                    UIContentSizeCategoryExtraLarge: 15,
                    UIContentSizeCategoryLarge: 13,
                    UIContentSizeCategoryMedium: 12,
                    UIContentSizeCategorySmall: 12,
                    UIContentSizeCategoryExtraSmall: 12
                ],
            ]
        }

        let contentSize = UIApplication.sharedApplication().preferredContentSizeCategory
        let style = Static.fontSizeTable[textStyle] as! NSDictionary
        return UIFontDescriptor(name: SubStruct.preferredFontName, size: CGFloat((style[contentSize] as! NSNumber).floatValue))
    }

}

Fehler auf Swift 3 mit Ihrer Lösung:'dispatch_once_t' is unavailable in Swift: Use lazily initialized globals instead
Thexande

1

So aktualisiere ich die Schriftart eines bevorzugten FontForTextStyle:

UIFont *font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
UIFontDescriptor *fontDesc = [font fontDescriptor];
fontDesc = [fontDesc fontDescriptorByAddingAttributes:@{UIFontDescriptorNameAttribute : @"Helvetica",
                                                        UIFontDescriptorSizeAttribute : @16}];

font = [UIFont fontWithDescriptor:fontDesc
                             size:[fontDesc pointSize]];

1

Ich wollte nur hineinspringen und sagen, dass es eine Bibliothek gibt, die dabei hilft, benutzerdefinierte Schriftarten zu integrieren und die Größenänderungen des dynamischen Typs zu bewältigen. Es heißt hilfreich Font ( https://github.com/adamyanalunas/Font ) und statt einer magischen Lösung wird eine Struktur eingerichtet, mit der jede benutzerdefinierte Schriftart beim Entfernen der Boilerplate unterschiedlich behandelt werden kann.

nb Ich bin der Autor dieser kleinen Bibliothek und ich denke, es ist ordentlich.


1

Hier ist meine Sicht auf die Antwort von @ Gobe in Swift 3:

extension UIFontDescriptor {

@nonobjc static var fontSizeTable: [UIFontTextStyle : [UIContentSizeCategory : CGFloat]] = {
    return [
        .headline: [
            .accessibilityExtraExtraExtraLarge: 23,
            .accessibilityExtraExtraLarge: 23,
            .accessibilityExtraLarge: 23,
            .accessibilityLarge: 23,
            .accessibilityMedium: 23,
            .extraExtraExtraLarge: 23,
            .extraExtraLarge: 21,
            .extraLarge: 19,
            .large: 17,
            .medium: 16,
            .small: 15,
            .extraSmall: 14],
        .subheadline: [
            .accessibilityExtraExtraExtraLarge: 21,
            .accessibilityExtraExtraLarge: 21,
            .accessibilityExtraLarge: 21,
            .accessibilityLarge: 21,
            .accessibilityMedium: 21,
            .extraExtraExtraLarge: 21,
            .extraExtraLarge: 19,
            .extraLarge: 17,
            .large: 15,
            .medium: 14,
            .small: 13,
            .extraSmall: 12],
        .body: [
            .accessibilityExtraExtraExtraLarge: 53,
            .accessibilityExtraExtraLarge: 47,
            .accessibilityExtraLarge: 40,
            .accessibilityLarge: 33,
            .accessibilityMedium: 28,
            .extraExtraExtraLarge: 23,
            .extraExtraLarge: 21,
            .extraLarge: 19,
            .large: 17,
            .medium: 16,
            .small: 15,
            .extraSmall: 14],
        .caption1: [
            .accessibilityExtraExtraExtraLarge: 18,
            .accessibilityExtraExtraLarge: 18,
            .accessibilityExtraLarge: 18,
            .accessibilityLarge: 18,
            .accessibilityMedium: 18,
            .extraExtraExtraLarge: 18,
            .extraExtraLarge: 16,
            .extraLarge: 14,
            .large: 12,
            .medium: 11,
            .small: 11,
            .extraSmall: 11],
        .caption2: [
            .accessibilityExtraExtraExtraLarge: 17,
            .accessibilityExtraExtraLarge: 17,
            .accessibilityExtraLarge: 17,
            .accessibilityLarge: 17,
            .accessibilityMedium: 17,
            .extraExtraExtraLarge: 17,
            .extraExtraLarge: 15,
            .extraLarge: 13,
            .large: 11,
            .medium: 11,
            .small: 11,
            .extraSmall: 11],
        .footnote: [
            .accessibilityExtraExtraExtraLarge: 19,
            .accessibilityExtraExtraLarge: 19,
            .accessibilityExtraLarge: 19,
            .accessibilityLarge: 19,
            .accessibilityMedium: 19,
            .extraExtraExtraLarge: 19,
            .extraExtraLarge: 17,
            .extraLarge: 15,
            .large: 13,
            .medium: 12,
            .small: 12,
            .extraSmall: 12],
    ]
}()

class func currentPreferredSize(textStyle: UIFontTextStyle = .body) -> CGFloat {
    let contentSize = UIApplication.shared.preferredContentSizeCategory
    guard let style = fontSizeTable[textStyle], let fontSize = style[contentSize] else { return 17 }
    return fontSize
}

class func preferredFontDescriptor(fontName: String = "SnellRoundhand", textStyle: UIFontTextStyle = .body) -> UIFontDescriptor {
    return UIFontDescriptor(name: fontName, size: currentPreferredSize())
}
}

0

Ab iOS 11 können Sie benutzerdefinierte Schriftarten, die im visuellen Editor konfiguriert wurden, programmgesteuert anpassen:

  1. Konfigurieren Sie Ihre benutzerdefinierte Schriftart mit dem visuellen Editor
  2. Passen Sie die Schriftgröße in der viewDidLoad-Methode an:
@IBOutlet weak var leftLangLabel: UILabel!

override func viewDidLoad() {
    super.viewDidLoad()

    leftLangLabel.font = UIFontMetrics.default.scaledFont(for: leftLangLabel.font)
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.