iOS Different Font Sizes within Single Size Class for Different Devices

前端 未结 7 1540
死守一世寂寞
死守一世寂寞 2020-12-01 05:32

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

相关标签:
7条回答
  • 2020-12-01 06:10

    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.

    0 讨论(0)
  • 2020-12-01 06:19

    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
    }
    
    0 讨论(0)
  • 2020-12-01 06:22

    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!

    0 讨论(0)
  • 2020-12-01 06:23

    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
    
    0 讨论(0)
  • 2020-12-01 06:24

    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;
        }
    }
    
    0 讨论(0)
  • 2020-12-01 06: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()

    0 讨论(0)
提交回复
热议问题