Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Different System Medium font on iOS 7

I'm setting a System Medium font on storyboard like this:

enter image description here

And this is the result for iOS 8:

enter image description here

But iOS 7 is showing a different (strange) font:

enter image description here

Am I setting something wrong?

like image 549
Douglas Ferreira Avatar asked Sep 09 '15 16:09

Douglas Ferreira


2 Answers

Running on this problem as well and this is my findings. This is a real mess.

There is no Medium system font on iOS7, they added it in iOS 8.2. On iOS7, after a long lag, it is picking the first font in alphabetical order (Academy Engraved).

Interestingly the iOS 7 bold system font is actually a Medium Helvetica Neue font:

(lldb) po [UIFont boldSystemFontOfSize:12]
<UICTFont: 0x12c58f8b0> font-family: ".HelveticaNeueInterface-MediumP4"; font-weight: bold; font-style: normal; font-size: 12.00pt

and the systemFont is a regular Helvetica Neue.

The Workaround for iOS 7 is to pick the System Bold font in interface builder, it does look thinner when it is running on an iOS7 device than it does on interface builder. Unfortunately, on iOS8 and iOS9, it really looks bold and not medium...

I ended up switching to Helvetica-Neue Medium for those cases which unfortunately means I have a mismatch of system font/San Francisco and Helvetica-Neue in some of my screens on iOS 9. Can't wait to get the green light to drop support for iOS7.

like image 93
Sebastien Windal Avatar answered Nov 03 '22 23:11

Sebastien Windal


I use method swizzling to fix this iOS 7 bug. My approach works well with Interface Builder.

UIFont+Swizzling.h

@import UIKit;

@interface UIFont (UIFont_Swizzle)

@end

UIFont+Swizzling.m

#import "UIFont+Swizzle.h"

@import ObjectiveC.runtime;

@implementation UIFont (UIFont_Swizzle)

+ (void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        if ([NSProcessInfo instancesRespondToSelector:@selector(operatingSystemVersion)]) return;
        Class class = object_getClass((id)self);

        SEL originalSelector = @selector(fontWithDescriptor:size:);
        SEL swizzledSelector = @selector(swizzled_fontWithDescriptor:size:);

        Method originalMethod = class_getClassMethod(class, originalSelector);
        Method swizzledMethod = class_getClassMethod(class, swizzledSelector);

        BOOL didAddMethod = class_addMethod(class,
                                            originalSelector,
                                            method_getImplementation(swizzledMethod),
                                            method_getTypeEncoding(swizzledMethod));

        if (didAddMethod) {
            class_replaceMethod(class,
                                swizzledSelector,
                                method_getImplementation(originalMethod),
                                method_getTypeEncoding(originalMethod));
        } else {
            method_exchangeImplementations(originalMethod, swizzledMethod);
        }
    });
}

+ (UIFont *)swizzled_fontWithDescriptor:(UIFontDescriptor *)descriptor size:(CGFloat)pointSize {
    id usageAttribute = descriptor.fontAttributes[@"NSCTFontUIUsageAttribute"];

    if (!descriptor.fontAttributes[UIFontDescriptorNameAttribute] &&
        [usageAttribute isKindOfClass:[NSString class]] &&
        [usageAttribute isEqualToString:@"CTFontMediumUsage"]) {
        descriptor = [descriptor fontDescriptorByAddingAttributes:@{UIFontDescriptorNameAttribute: @"HelveticaNeue-Medium"}];
    }
    id font = [self swizzled_fontWithDescriptor:descriptor size:pointSize];

    return font;
}

@end

Special thanks for Xtrace's creator :)

like image 4
Andrew Vyazovoy Avatar answered Nov 03 '22 21:11

Andrew Vyazovoy