How to use a custom font with dynamic text sizes in iOS7

前端 未结 12 2015
长情又很酷
长情又很酷 2020-11-29 14:41

In iOS7 there are new API\'s for getting a font that is automatically adjusted to the text size the user has set in their preferences.

It looks something like this to

相关标签:
12条回答
  • 2020-11-29 15:30

    This is how I do it in Swift. I like this because it's more general, it only requires one table, and it should work well with any font. First I wrote a generalized multiplier (in a 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
            }
        }
    }
    

    Then I update the font (e.g., in the observer) using a UIFontDescriptor like this:

    textView.font = UIFont(descriptor: fontDescriptor!, size: fontDescriptor!.pointSize * fontSizeMultiplier)
    
    0 讨论(0)
  • 2020-11-29 15:30

    In iOS 11 you can use:

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

    See also Building Apps with Dynamic Type WWDC 2017 - Session 245 - iOS time 8:34.

    0 讨论(0)
  • 2020-11-29 15:30

    Swift 2.1-3.0 code based on @smartDonkey's port of @Bob Spryn code. Also updated with the Apple sizes from @Klaas.

    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))
        }
    
    }
    
    0 讨论(0)
  • 2020-11-29 15:33

    Here is my take on @Gobe's answer, 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 讨论(0)
  • 2020-11-29 15:34

    @Bob Spryn code rewritten with swift:

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

    Usage:

    UIFont(descriptor: UIFontDescriptor.preferredDescriptor(UIFontTextStyleBody), size: 0)
    
    0 讨论(0)
  • 2020-11-29 15:35

    In iOS 11 UIFontMetrics class was introduced. Create a FontMetrics object for the text style that you're interested in. Then choose any font you want, sized for the standard dynamic type size. And then you can ask the FontMetrics object to scale that font given the user's current settings.

    let bodyMetrics = UIFontMetrics(forTextStyle: .body)
    let standardFont = ... // any font you want, for standard type size
    let font = bodyMetrics.scaledFont(for: standardFont)
    
    0 讨论(0)
提交回复
热议问题