简体   繁体   English

不同设备的单一尺寸类别中的iOS不同字体大小

[英]iOS Different Font Sizes within Single Size Class for Different Devices

In iOS 8, we can design a different UI layout for each size class. 在iOS 8中,我们可以为每个尺寸类设计不同的UI布局。 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. 我面临的问题是,我设计了一个紧凑宽度和常规高度的布局(纵向所有iPhone的尺寸等级),但我希望保持3.5和4英寸设备的标签字体较小(iPhone 4和5 ),然后相对较大的4.7英寸(iPhone 6)和更大的5.5英寸(iPhone 6 Plus)设备。 I've searched but unable to find a solution to set different font size for different devices within same size class. 我已搜索但无法找到解决方案为同一大小类中的不同设备设置不同的字体大小。

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. 假设有一个新的iPhone型号出现,如果您使用自动布局和大小类,则不必手动修复所有约束以使您的应用与此新设备兼容。 However, you can still set the font size of the UILabel using the following code: 但是,您仍然可以使用以下代码设置UILabel的字体大小:

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. 我正在使用UILabel Custom类UILabel扩展UIDevice扩展作为通用解决方案在Swift 3+的项目中处理它。

UIDevice extension to get screenType : 获取screenType UIDevice扩展

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. 以下是使用screenType调整字体大小的UILabel扩展 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. adjustsFontSizeToFitDevice方法也可以添加到UILabel自定义类中 ,但我已将它放在UILabel扩展中 ,以使其可从所有类型的UILabel实例访问。

The constant "2" used in adjustsFontSizeToFitDevice method can be changed to any desired number. adjustsFontSizeToFitDevice方法中使用的常量“2”可以更改为任何所需的数字。 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. 我的逻辑是将iPhone 6/7/8视为默认分辨率,并为该分辨率的每个标签提供合适的字体大小(在Storyboard中 )。 Then, I'm adding 2 points for iPhone X and iPhone 6/7/8 Plus, whereas subtracting 2 points for iPhone 4/5. 然后,我为iPhone X和iPhone 6/7/8 Plus增加了2分,而为iPhone 4/5减去了2分。

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 . 最后是一个UILabel自定义类 ,用于将字体调整应用于从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. 用法:Storyboard中 ,子类来自MyCustomLabel的所有UILabel实例,其字体大小需要根据设备大小进行调整。

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. Usage : 不使用14作为字体大小, 您可以使用14.fontSize ,它将根据设备更改,取决于您的delta值。

No need to add conditions everyWhere in code. 无需在代码中添加条件。 Only one time as below. 只有一次如下。

Usage: UIFont.font_medium(12.fontSize) 用法: UIFont.font_medium(12.fontSize)

UIFont extension: UIFont扩展:

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

UIDevice Extension: UIDevice扩展:

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: Int扩展:

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;
    }
}

Two ways: 两种方式:

1)Manually make a method in app delegate, share its object and call method. 1)在app delegate中手动创建一个方法,共享它的对象和调用方法。

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. 2)在每个UI项目上,转到属性检查器,声明一个字体。

(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! 快乐的编码!

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

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 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
}

Thats the way how I did it. 这就是我做的方式。 It's written in Swift 4 :) 它是用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() 用法: myawesomeLabel.adjustFontSizeForDevice()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM