iOS Different Font Sizes within Single Size Class for Different Devices iOS Different Font Sizes within Single Size Class for Different Devices ios ios

iOS Different Font Sizes within Single Size Class for Different Devices


Edit: I don't recommend this anymore. This approach doesn't scale well when new devices come out. Use a combination of dynamic font sizes and size classes-specific fonts.


Say a new iPhone model comes out, if you are using Auto Layout and Size Classes you don't have to fix all the constraints manually to make your app compatible with this newer device. However, you can still set the font size of the UILabel using the following code:

if UIScreen.mainScreen().bounds.size.height == 480 {    // iPhone 4    label.font = label.font.fontWithSize(20)     } else if UIScreen.mainScreen().bounds.size.height == 568 {    // IPhone 5    label.font = label.font.fontWithSize(20)} else if UIScreen.mainScreen().bounds.size.width == 375 {    // iPhone 6    label.font = label.font.fontWithSize(20)} else if UIScreen.mainScreen().bounds.size.width == 414 {    // iPhone 6+    label.font = label.font.fontWithSize(20)} else if UIScreen.mainScreen().bounds.size.width == 768 {    // iPad    label.font = label.font.fontWithSize(20)}


I'm handling it in a project in Swift 3+ using a UILabel Custom class, UILabel extension, and UIDevice extension as generic solution.

UIDevice extension to get screenType:

public extension UIDevice {    var iPhone: Bool {        return UIDevice().userInterfaceIdiom == .phone    }    enum ScreenType: String {        case iPhone4        case iPhone5        case iPhone6        case iPhone6Plus        case iPhoneX        case Unknown    }    var screenType: ScreenType {        guard iPhone else { return .Unknown}        switch UIScreen.main.nativeBounds.height {        case 960:            return .iPhone4        case 1136:            return .iPhone5        case 1334:            return .iPhone6        case 2208:            return .iPhone6Plus        case 2436:            return .iPhoneX        default:            return .Unknown        }    }}

Following is the UILabel extension that uses screenType to adjust font size. adjustsFontSizeToFitDevice method could be added in UILabel custom class too, but I've put it in UILabel extension to make it accessible from all types of UILabel instances.

The constant "2" used in adjustsFontSizeToFitDevice method can be changed to any desired number. My logic is to consider iPhone 6/7/8 as default resolution, and give suitable font size (in Storyboard) to each label for that resolution. Then, I'm adding 2 points for iPhone X and iPhone 6/7/8 Plus, whereas subtracting 2 points for iPhone 4/5.

extension UILabel {    func adjustsFontSizeToFitDevice() {        switch UIDevice().screenType {        case .iPhone4, .iPhone5:            font = font.withSize(font.pointSize - 2)            break        case .iPhone6Plus, .iPhoneX:            font = font.withSize(font.pointSize + 2)            break        default:            font = font.withSize(font.pointSize)        }    }}

Finally a UILabel custom class to apply font adjustment to all labels that are sub-classed from MyCustomLabel.

class MyCustomLabel: UILabel {    // MARK: - Life Cycle Methods    override func awakeFromNib() {        super.awakeFromNib()        adjustsFontSizeToFitDevice()    }}

Usage:In Storyboard, sub-class all those instances of UILabel from MyCustomLabel whose font size needs to be adjusted according to device size.


You can achieve desired effect as below.

Usage : instead of using 14 as font size you can use 14.fontSize, it will changed as per device, depends on you delta value.

No need to add conditions everyWhere in code. Only one time as below.

Usage: UIFont.font_medium(12.fontSize)

UIFont extension:

extension UIFont {        class func font_medium(_ size : CGFloat) -> UIFont {        return UIFont(name: "EncodeSans-Medium", size: size)!;    }    }

UIDevice Extension:

extension UIDevice {    enum DeviceTypes {        case iPhone4_4s        case iPhone5_5s        case iPhone6_6s        case iPhone6p_6ps        case after_iPhone6p_6ps    }    static var deviceType : DeviceTypes {        switch UIScreen.main.height {        case 480.0:            return .iPhone4_4s        case 568.0:            return .iPhone5_5s        case 667.0:            return .iPhone6_6s        case 736.0:            return .iPhone6p_6ps        default:            return .after_iPhone6p_6ps        }    }}

Int Extension:

extension Int{    var fontSize : CGFloat {        var deltaSize : CGFloat = 0;        switch (UIDevice.deviceType) {        case .iPhone4_4s,             .iPhone5_5s :            deltaSize = -1;        case .iPhone6_6s :            deltaSize = 2;        case .iPhone6p_6ps :            deltaSize = 2;        default:            deltaSize = 0;        }        let selfValue = self;        return CGFloat(selfValue) + deltaSize;    }}