scaledValueForValue: called on a font that doesn&#

2019-01-31 15:57发布

问题:

I am currently using the Xcode 6 pre release (not beta) and the simulator on OS X 10.10 Yosemite beta 7. I am trying to build a project developed in xcode 6, but the app crashes whenever I open a certain view controller. This view controller literally has no code in it (it is an empty, static, table view controller that has a couple of default cells and labels).

The error given is:

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason:  
'scaledValueForValue: called on a font that doesn't have a text style set'

And right before I am given this assertion failure:

*** Assertion failure in -[UICTFont _scaledValueForValue:],         
/SourceCache/UIFoundation_Sim/UIFoundation-371/UIFoundation/iOS/UIFont.m:496

I seriously have no idea what is going on, I tried setting breakpoints in the VC but the error happens after the viewDidLoad method is called (and thus after all my code is executed).

Any Ideas? The fonts for everything in my project is 'Baskerville' and I have tried changing that but it does not affect the crash.

Oh, and it works fine if I use Xcode 5.

Update 9/24: So I am still unable to figure this out. I tried using the fontWithDescriptor method, but it still crashes. The funny thing is, I have plenty of pages that use custom fonts and most of them work fine, but there are two VCs that crash immediately when I go to them... one of them doesn't even have any custom fonts. I really appreciate all of your feedback, but does anyone have any other ideas/fixes? I am using the official release of Xcode and it still doesn't work.

回答1:

This problem has been fixed in iOS 8.1.

Instead of spending time building a custom header/footer view, I just not apply the custom font to devices running iOS 8.0. Most people will probably have updated to iOS 8.1 anyway.

I use the following code for this:

NSOperatingSystemVersion iOS_8_1 = (NSOperatingSystemVersion){8, 1, 0};

if (![[NSProcessInfo processInfo] respondsToSelector:@selector(isOperatingSystemAtLeastVersion:)]
    || [[NSProcessInfo processInfo] isOperatingSystemAtLeastVersion:iOS_8_1]) {
    header.textLabel.font = [UIFont fontWithName:@"Avenir-Medium" size:header.textLabel.font.pointSize];
}

The first statement is true if the device is running an iOS version lower than 8 (since isOperatingSystemAtLeastVersion: was introduced in iOS 8.0). The second statement is true if the device if running iOS 8.1 or later. With both statements we thus only exclude devices running iOS 8.0.



回答2:

Okay I finally figured it out.

This occurs when grouped table views have section headers and possibly footers. As a temporary workaround I am just removing the headers/footers from the grouped tableviews, but if you really need the font you can create a custom header view by overriding the "viewForHeaderInSection", and setting the font on your custom view's label.

Still, this is definitely a bug in iOS 8 and hopefully it will be fixed soon.



回答3:

Like everyone here, applying the fix in other answers caused the font setting to be ignored. What I ended up doing was having my own UITableViewHeaderFooterView (Where it seems the cause for the crash is coming from) subclasses that had a label that I added myself. I then used this label instead of the textLabel property inherited from UITableViewHeaderFooterView, set up the auto layout constraints, set the font, and all was right once again (though not what I would consider ideal). I'll add again that this seems to be iOS 8 unique.



回答4:

Take a look at: http://openradar.io/17623734

Unfortunately at this early stages of xCode 6 I can only offer a workaround for the crash.

Replace this line:

[header.textLabel setFont:[UIFont fontWithName:@"HelveticaNeue-Bold" size:17]];

for this:

header.textLabel.font = [UIFont fontWithDescriptor:[UIFontDescriptor fontDescriptorWithFontAttributes:@{@"NSCTFontUIUsageAttribute" : UIFontTextStyleBody,
                                                                                                        @"NSFontNameAttribute" : @"HelveticaNeue-Italic"}] size:17.0];


回答5:

Finally found workaround. It is simple, you just need to construct font in other direction :)

// 1. Grab your custom font
CGFloat size = 17.0f;
UIFont *font = [UIFont fontWithName:@"Brandon Grotesque" size:size];

// 2. Get descriptor for your font and create new descriptor with
UIFontDescriptorTextStyleAttribute and UIFontDescriptorSizeAttribute attributes from it.

UIFontDescriptor *des = [[font fontDescriptor] fontDescriptorByAddingAttributes:@{
   UIFontDescriptorTextStyleAttribute: UIFontTextStyleBody, // You can tune this style based on usage
   UIFontDescriptorSizeAttribute: @(size)
}];

// 3. Get your font
UIFont *finalFont = [UIFont fontWithDescriptor:des size:0.0]


回答6:

This problem is still present in iOS 8.0.2 but seems to be fixed in 8.1.

My workaround was to set the custom font only if iOS is greater than 8.0.2:

#define SYSTEM_VERSION_GREATER_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedDescending)

...

if (SYSTEM_VERSION_GREATER_THAN(@"8.0.2")) {
    [[UILabel appearanceWhenContainedIn:[UITableViewHeaderFooterView class], nil] setFont:[UIFont fontWithName:@"Helvetica" size:14.0]];
}


回答7:

This only happens for me when using either a UITableView or UITableViewController where initWithStyle: method call is set to UITableViewStyleGrouped. Changing the style to UITableViewStylePlain resolved the issues.



回答8:

Same problem here: set a custom font for UITableViewHeaderFooterView in my app init, get this crash when showing a grouped UITableView.

What works for me is to delay customisation until the view controller is being created, i.e. do whatever you would have done at app init in the view controller's init. Irritating, but works for me.

- (id) init
{
  ...

  if (self = [super init])
  {
    // customise table view headers
    UILabel *headerLabel =
      [UILabel appearanceWhenContainedIn: [UITableViewHeaderFooterView class], nil];

    headerLabel.font =
      [UIFont fontWithName: @"AvenirNext-Medium" size: 15];

    ...
  }
}