In iOS 8, we can design a different UI layout for each size class. The issue I'm facing is, I've designed a layout for Compact Width and Regular Height (size class for all iPhones in portrait) but i want to keep font size of labels smaller for 3.5 and 4 inch devices (iPhone 4 and 5), then relatively bigger for 4.7 inch (iPhone 6) and more bigger for 5.5 inch (iPhone 6 Plus) devices. I've searched but unable to find a solution to set different font size for different devices within same size class.
-
3"I've searched but unable to find a solution to set different font size for different devices within same size class." You are quite right - there is no simple solution (presumably because Apple doesn't really want you to do that). If it's really important to you to do, you'll have to use code to detect the screen size and change the font size of the label accordingly. – matt Jan 22 '15 at 19:44
-
Thanks matt, i just needed to cross check my understanding. – Maverick Jan 24 '15 at 14:03
-
3It's not an unreasonable idea, though. You should file an enhancement request with Apple. Size classes are too coarse-grained... – matt Jan 24 '15 at 17:28
-
You are quite right, i have added one best solution. Please find my answer in this thread. I think it will help you :) – Sandip Patel - SM Mar 03 '17 at 10:47
7 Answers
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)
}

- 9,139
- 16
- 78
- 130
-
It doesn't "work the same for a UILabel". You are merely changing the size of a button. That has no effect on the font size of text. – matt Jan 22 '15 at 19:42
-
If you'll want to use this then **do not use size classes** for fonts – WINSergey Feb 15 '16 at 12:17
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.

- 3,209
- 1
- 34
- 40
-
1out of all answers here on stackoverflow regarding same topic this is far more convenient ..But still it is not perfect. As I need to change every label in storyboard. I am looking for solution which will change font same like above ans ...font = font.withSize(font.pointSize + 2) w.r.t only iPhone screen sizes in portrait mode from a single place in app (may be from app delegate) .Also at same time I don't want to loose any font style (bold/regular ) set in storyboard. – Apple_Magic Jun 06 '20 at 11:17
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;
}
}

- 4,871
- 2
- 22
- 29
Two ways:
1)Manually make a method in app delegate, share its object and call method.
eg :
var device = UIDevice.currentDevice().model
if (device == "iPhone" || device == "iPhone Simulator" || device == "iPod touch")
{
labelboarder.frame = CGRectMake(0,self.usernameTF.frame.height-10, self.usernameTF.frame.width, 1)
labelboarder1.frame = CGRectMake(0,self.usernameTF.frame.height-10, self.usernameTF.frame.width,1)
}
else
{
labelboarder.frame = CGRectMake(0,self.usernameTF.frame.height, 500, 1)
labelboarder1.frame = CGRectMake(0,self.usernameTF.frame.height, 500,1)
}
2) On every UI item, go to attributes inspector, declare a font.
(There is a + sign visible to the left of Font size field. Click on it ,select the matching size class and declare font size.)
The second option is convenient for me. Happy Coding!

- 1,977
- 27
- 39

- 14,148
- 92
- 64
-
The question was: "How to set different font size for different devices within same size class". Your comment doesn't answer that. – Maverick Sep 07 '15 at 12:09
-
How do you do it on iPhone6 Plus? iPhone6 Plus fonts looks small compared to iPhone5 iPhone5 and iPhone6Plus Portrain have same size classes h- Companct v- Regular – Basil Mariano Mar 12 '16 at 03:05
-
@ Maverick : Setting different font size for UI elements based on Device screen size is not a good practice. The text should be on readable font size and clear. Please refer Apple's Human UI Guidelines. Yes, we can set different font size for different size classes - Thats recommended. – Alvin George Mar 15 '16 at 05:28
Instead of writing code for each and every label, do just extend your label class with Your custom label class as below and it will automatically scale based on device resolution scaling factor:
#define SCALE_FACTOR_H ( [UIScreen mainScreen].bounds.size.height / 568 )
CustomLabel.h
#import <UIKit/UIKit.h>
@interface CustomLabel : UILabel
@end
CustomLabel.m
#import "CustomLabel.h"
@implementation CustomLabel
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code
}
*/
- (id)initWithCoder:(NSCoder *)aDecoder {
if( (self = [super initWithCoder:aDecoder]) ){
[self layoutIfNeeded];
[self configurefont];
}
return self;
}
- (void) configurefont {
CGFloat newFontSize = (self.font.pointSize * SCALE_FACTOR_H);
self.font = [UIFont fontWithName:self.font.fontName size:newFontSize];
}
@end

- 3,346
- 29
- 27
Thats the way how I did it. It's written in Swift 4 :)
enum DeviceSize {
case big, medium, small
}
protocol Fontadjustable {
var devicetype: DeviceSize { get }
func adjustFontSizeForDevice()
}
extension UILabel: Fontadjustable {
var devicetype: DeviceSize {
switch UIScreen.main.nativeBounds.height {
case 1136:
return .small
case 1334:
return .medium
case 2208:
return .big
case 2436:
return .big
default:
return .big
}
}
func adjustFontSizeForDevice() {
switch self.devicetype {
case .small:
self.font = font.withSize(font.pointSize)
case .medium:
self.font = font.withSize(font.pointSize + 5)
case .big:
self.font = font.withSize(font.pointSize + 10)
}
}
}
USAGE : myawesomeLabel.adjustFontSizeForDevice()

- 8,132
- 4
- 50
- 71
-
This needs more love. It's a pretty solid solution. Thanks for sharing. – Greg Ellis May 10 '20 at 01:09
Create like this,
#define VIEWHEIGHT ([[UIScreen mainScreen] bounds].size.height)
#define VIEWWIDTH ([[UIScreen mainScreen] bounds].size.width)
#define FONTNAME_LIGHT @"AppleSDGothicNeo-Regular"
#define FONTNAME_BOLD @"AppleSDGothicNeo-Bold"
#define LFONT_16 [UIFont fontWithName:FONTNAME_LIGHT size:16]
after that where you want to change label font we can write simple Switch case
switch ((VIEWHEIGHT == 568)?1:((VIEWHEIGHT == 667)?2:3)) {
case 1:{
boldFont = BFONT_16;
}
break;
case 2:{
privacyFont = LFONT_18;
boldFont = BFONT_18;
}
break;
default:{
privacyFont = LFONT_20;
boldFont = BFONT_20;
}
break;
}
Swift Version
func isPhoneDevice() -> Bool {
return UIDevice.current.userInterfaceIdiom == .phone
}
func isDeviceiPad() -> Bool {
return UIDevice.current.userInterfaceIdiom == .pad
}
func isPadProDevice() -> Bool {
let SCREEN_WIDTH = Float(UIScreen.main.bounds.size.width)
let SCREEN_HEIGHT = Float(UIScreen.main.bounds.size.height)
let SCREEN_MAX_LENGTH: Float = fmax(SCREEN_WIDTH, SCREEN_HEIGHT)
return UIDevice.current.userInterfaceIdiom == .pad && SCREEN_MAX_LENGTH == 1366.0
}
func isPhoneXandXSDevice() -> Bool {
let SCREEN_WIDTH = CGFloat(UIScreen.main.bounds.size.width)
let SCREEN_HEIGHT = CGFloat(UIScreen.main.bounds.size.height)
let SCREEN_MAX_LENGTH: CGFloat = fmax(SCREEN_WIDTH, SCREEN_HEIGHT)
return UIDevice.current.userInterfaceIdiom == .phone && SCREEN_MAX_LENGTH == 812.0
}
func isPhoneXSMaxandXRDevice() -> Bool {
let SCREEN_WIDTH = CGFloat(UIScreen.main.bounds.size.width)
let SCREEN_HEIGHT = CGFloat(UIScreen.main.bounds.size.height)
let SCREEN_MAX_LENGTH: CGFloat = fmax(SCREEN_WIDTH, SCREEN_HEIGHT)
return UIDevice.current.userInterfaceIdiom == .phone && SCREEN_MAX_LENGTH == 896.0
}

- 1,165
- 1
- 13
- 37