Use of the Expanded/Condensed SF Font Families in iOS 16

I just finished the video regarding the new Expanded/Condensed SF font variants. I was trying to work out how to use them in my apps, but can't seem to find them anywhere. I'd have guessed they would be in the SwiftUI's Font element as a new .design option, but I didn't see them. Has anyone found them yet, or are they not in the first beta?

Post not yet marked as solved Up vote post of dtsdts Down vote post of dtsdts
1.5k views

Replies

I've been able to experiment with this a bit. You have to set a 'width' attribute trait on the font descriptor. Apologies for the Objective-C, but hopefully this will give you enough to figure it out!

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    ADTSystemFontTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:[ADTSystemFontTableViewCell reuseIdentifier] forIndexPath:indexPath];

    UIFontDescriptor *fontDescriptor = [self fontDescriptorAtIndexPath:indexPath];

    NSDictionary *widthSetting = @{UIFontWidthTrait     : @(-1.0)};
    fontDescriptor = [fontDescriptor fontDescriptorByAddingAttributes:@{UIFontDescriptorTraitsAttribute: widthSetting}];

    cell.fontDescriptor = fontDescriptor;
    cell.title = [self titleForRowAtIndexPath:indexPath];
    cell.showFontName = [ADTAppSettingsManager sharedInstance].showSystemFontsInfo.value;

    return cell;
}

However, in my testing it seems that only the regular SF font design, and not rounded, serif and monospaced, work. I'm not entirely sure whether the width is just another way to vary the base default SF design, or whether it is intended to be a separate dimension like point size and weight that should work across all designs.

Thanks to the tip from @hacknicity, here's an example in Swift for UIKit:

var descriptor = UIFontDescriptor.preferredFontDescriptor(withTextStyle: .largeTitle)
let traits: [UIFontDescriptor.TraitKey:Any] = [.width: -1.0]
descriptor = descriptor.addingAttributes([.traits: traits])
let uiFont = UIFont(descriptor: descriptor, size: descriptor.pointSize)

This creates a narrow version of the "large title" text style.

According to the header file, the width value should be a float between -1.0 to 1.0. -1.0 will give you a narrow width, 0.0 is a normal width, and 1.0 is wide. There are options between those values—for example 0.25 gave me a width that's just a bit more narrow than normal.

It seems there's not a direct equivalent of UIFontDescriptor in SwiftUI. However, you can create a SwiftUI Font from a UIFont. Just add one more line to the example above:

let font = Font(uiFont as CTFont)

I imagine this will become easier to use in a later beta.