objective-cuilabeluifontuifontdescriptor

Creating Font Descriptors with Fractions in Objective C


I am having trouble displaying fractions in Objective C, even though the equivalent code works in Swift. I must be missing something very obvious??

Swift Code:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    //: Playground - noun: a place where people can play

    let pointSize = self.label.font.pointSize

    let systemFontDesc = UIFont.systemFont(ofSize: pointSize, weight: UIFontWeightLight).fontDescriptor

    let fractionFontDesc = systemFontDesc.addingAttributes(
        [
            UIFontDescriptorFeatureSettingsAttribute: [
                [
                    UIFontFeatureTypeIdentifierKey: kFractionsType,
                    UIFontFeatureSelectorIdentifierKey: kDiagonalFractionsSelector,
                    ], ]
        ] )

    print(fractionFontDesc)
    self.label.font = UIFont(descriptor: fractionFontDesc, size:pointSize)

    print("label.font.descriptor: \(self.label.font.fontDescriptor)")
}

Result:

swift result

equivalent code in Objective C

-(void) viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];

    CGFloat pointSize = _label.font.pointSize;

    UIFontDescriptor *systemFontDesc = [UIFont systemFontOfSize:pointSize weight:UIFontWeightLight].fontDescriptor;

    UIFontDescriptor *fractionDescriptor = [systemFontDesc fontDescriptorByAddingAttributes:@{ UIFontDescriptorFeatureSettingsAttribute : @{
                                                                                                       UIFontFeatureTypeIdentifierKey: @(11), // kFractionsType
                                                                                                       UIFontFeatureSelectorIdentifierKey: @(2)}}]; // kDiagonalFractionsSelector

    NSLog(@"%@\n\n", fractionDescriptor);

    UIFont *fracFont = [UIFont fontWithDescriptor:fractionDescriptor size:pointSize];

    NSLog(@"fracFont.fontDescriptor: %@\n\n", fracFont.fontDescriptor);

    [_label setFont: fracFont];

    NSLog(@"label.font.descriptor: %@\n\n", _label.font.fontDescriptor);
}

Result:

objective c output


Solution

  • The problem is the expression

    fontDescriptorByAddingAttributes:@{
       UIFontDescriptorFeatureSettingsAttribute : @{
    

    That last @{ indicates that your UIFontDescriptorFeatureSettingsAttribute is a dictionary. That is wrong. It needs to be an array of dictionaries. (Look carefully at your original Swift code and you will see that this is so.)

    You would do much better, in my opinion, to form your dictionary in one line, make an array of it in another line, and call fontDescriptorByAddingAttributes in a third line. That way you'll be clear on what you're doing. Right now you're just confusing the heck out of yourself with all those nested literals...