Limit supported Dynamic Type font sizes

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

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]