Custom Font Sizing in Xcode 6 Size Classes not working properly with Custom Fonts
Fast fix:
1) Set fonts as System for size classes
2) Subclass UILabel and override "layoutSubviews" method like:
- (void)layoutSubviews{ [super layoutSubviews]; // Implement font logic depending on screen size if ([self.font.fontName rangeOfString:@"bold" options:NSCaseInsensitiveSearch].location == NSNotFound) { NSLog(@"font is not bold"); self.font = [UIFont fontWithName:@"Custom regular Font" size:self.font.pointSize]; } else { NSLog(@"font is bold"); self.font = [UIFont fontWithName:@"Custom bold Font" size:self.font.pointSize]; }}
By the way, it is a very convenient technique for iconic fonts
After trying everything, I eventually settled on a combination of the above solutions. Using Xcode 7.2, Swift 2.
import UIKitclass LabelDeviceClass : UILabel { @IBInspectable var iPhoneSize:CGFloat = 0 { didSet { if isPhone() { overrideFontSize(iPhoneSize) } } } @IBInspectable var iPadSize:CGFloat = 0 { didSet { if isPad() { overrideFontSize(iPadSize) } } } func isPhone() -> Bool { // return UIDevice.currentDevice().userInterfaceIdiom == .Phone return !isPad() } func isPad() -> Bool { // return UIDevice.currentDevice().userInterfaceIdiom == .Pad switch (UIScreen.mainScreen().traitCollection.horizontalSizeClass, UIScreen.mainScreen().traitCollection.verticalSizeClass) { case (.Regular, .Regular): return true default: return false } } func overrideFontSize(fontSize:CGFloat){ let currentFontName = self.font.fontName if let calculatedFont = UIFont(name: currentFontName, size: fontSize) { self.font = calculatedFont } }}
@IBInspectable
lets you set the font size in the Storyboard- It uses a
didSet
observer, to avoid the pitfalls fromlayoutSubviews()
(infinite loop for dynamic table view row heights) andawakeFromNib()
(see @cocoaNoob's comment) - It uses size classes rather than the device idiom, in hopes of eventually using this with
@IBDesignable
- Sadly,
@IBDesignable
doesn't work withtraitCollection
according to this other stack article - The trait collection switch statement is performed on
UIScreen.mainScreen()
rather thanself
per this stack article
Workaround for UILabel
: keep the same font size on all Size Classes, but instead change your label height accordingly in each Size Class. Your label must have autoshrink enabled. It worked nicely in my case.