Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Limit supported Dynamic Type font sizes

I want to support Dynamic Type but only to a certain limit, similar to the Settings.app where standard UITableViewCells can grow up to UIContentSizeCategoryAccessibilityExtraExtraLarge but not larger.

Is there an easy way to accomplish this with standard UITableViewCell styles?

like image 941
Ortwin Gentz Avatar asked Oct 14 '14 21:10

Ortwin Gentz


People also ask

What is dynamic font sizing?

The Dynamic Type feature allows users to choose the size of textual content displayed on the screen. It helps users who need larger text for better readability. It also accommodates those who can read smaller text, allowing more information to appear on the screen.

What is a dynamic font?

ABSTRACT: Dynamic fonts are fonts whose character shape is defined every time the correspond- ing character is printed rather than when the font is defined as a whole. Such fonts allow, for example.

What is dynamic type accessibility?

Dynamic Type is a feature on iOS that enables the app's content to scale based on the user's preferred content size. It helps users who need larger text for better readability. And it also accommodates those who can read smaller text, allowing for more information to appear on the screen.

How do you support dynamic type?

To add support for Dynamic Type in your app, you use text styles. A text style describes the use of the text, such as headline or body or title1 , and lets the system know how best to adjust its size. You can configure text styles in either Interface Builder or your source code.


2 Answers

I'm using a custom category on UIFont to get a preferred font with a limit, like this

extension UIFont {

  static func preferredFont(withTextStyle textStyle: UIFont.TextStyle, maxSize: CGFloat) -> UIFont {
    // Get the descriptor
    let fontDescriptor = UIFontDescriptor.preferredFontDescriptor(withTextStyle: textStyle)

    // Return a font with the minimum size
    return UIFont(descriptor: fontDescriptor, size: min(fontDescriptor.pointSize, maxSize))
  }

}

ObjC

@implementation UIFont (preferredFontWithSizeLimit)

+ (UIFont *)preferredFontWithTextStyle:(UIFontTextStyle)style maxSize:(CGFloat)maxSize {
    // Get the descriptor
    UIFontDescriptor *fontDescriptor = [UIFontDescriptor preferredFontDescriptorWithTextStyle: style];

    // Return a font with the minimum size
    return [UIFont fontWithDescriptor: fontDescriptor size: MIN(fontDescriptor.pointSize, maxSize)];
}

@end

To hard-code limits based on the style, you could add something like this (I put the current system default for each style in comments)

+ (UIFont *)limitedPreferredFontForTextStyle:(UIFontTextStyle)style {
    // Create a table of size limits once
    static NSDictionary *sizeLimitByStyle;
    static dispatch_once_t once_token;
    dispatch_once(&once_token, ^{
        sizeLimitByStyle = @{
            UIFontTextStyleTitle1: @56, // default 28
            UIFontTextStyleTitle2: @44, // default 22
            UIFontTextStyleTitle3: @40, // default 20
            UIFontTextStyleHeadline: @34, // default 17
            UIFontTextStyleSubheadline: @30, // default 15
            UIFontTextStyleBody: @34, // default 17
            UIFontTextStyleCallout: @32, // default 16
            UIFontTextStyleFootnote: @26, // default 13
            UIFontTextStyleCaption1: @24, // default 12
            UIFontTextStyleCaption2: @22, // default 11
        };
    });
    
    // Look up the size limit
    CGFloat maxSize = INFINITY;
    NSNumber *limit = sizeLimitByStyle[style];
    if (limit) {
        maxSize = limit.doubleValue;
    }
    // Return the font
    return [UIFont preferredFontWithTextStyle: style maxSize: maxSize];
}
like image 81
John Stephen Avatar answered Oct 08 '22 18:10

John Stephen


I couldn't find any solution using existing UIKit methods. But there is a simple way to achieve this.

  1. Create a new method - [UIFont gvc_preferredFontForTextStyle:]

Here font size grows upto UIContentSizeCategoryExtraExtraExtraLarge and remains constant afterwords. Related question

+ (UIFont *)gvc_preferredFontForTextStyle:(NSString *)style {
 static dispatch_once_t onceToken;
 static NSDictionary *fontSizeTable;
 dispatch_once(&onceToken, ^{
   fontSizeTable = @{
     UIFontTextStyleBody: @{
      UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: @23,
      UIContentSizeCategoryAccessibilityExtraExtraLarge: @23,
      UIContentSizeCategoryAccessibilityExtraLarge: @23,
      UIContentSizeCategoryAccessibilityLarge: @23,
      UIContentSizeCategoryAccessibilityMedium: @23,
      UIContentSizeCategoryExtraExtraExtraLarge: @23,
      UIContentSizeCategoryExtraExtraLarge: @21,
      UIContentSizeCategoryExtraLarge: @19,
      UIContentSizeCategoryLarge: @17,
      UIContentSizeCategoryMedium: @16,
      UIContentSizeCategorySmall: @15,
      UIContentSizeCategoryExtraSmall: @14,},

 };
 });


 NSString *contentSize = [UIApplication sharedApplication].preferredContentSizeCategory;
 CGFloat fontSize = ((NSNumber *)fontSizeTable[style][contentSize]).floatValue;
 return [UIFont systemFontOfSize:fontSize];
  1. Use [UIFont gvc_preferredFontForTextStyle:] to set font in code

cell.font = [UIFont gvc_preferredFontForTextStyle:UIFontTextStyleBody]

like image 45
db42 Avatar answered Oct 08 '22 18:10

db42