美文网首页
iOS字体大小的自动适配(代码&xib)

iOS字体大小的自动适配(代码&xib)

作者: 田淳_13fe | 来源:发表于2019-07-06 17:44 被阅读0次

基本原理

1.计算iPhone屏幕尺寸与UI设计稿的尺寸比例

2.利用runtime机制,将原始字体大小值进行比例缩放,并替换原生方法的实现

代码适配替换方法(UIFont),可根据需求自行追加其他方法:

+ (UIFont *)systemFontOfSize:(CGFloat)fontSize;
+ (nullable UIFont *)fontWithName:(NSString *)fontName size:(CGFloat)fontSize;

xib适配替换方法(UILabel):

- (void)awakeFromNib;

代码适配

#import "UIFont+ScaleAdapter.h"
#import <objc/runtime.h>

//UI设计图宽度
#define DesignWidth 414.0
//缩放比例
#define Scaling ((CGFloat)([UIScreen mainScreen].bounds.size.width / DesignWidth))

@implementation UIFont (ScaleAdapter)

+ (void)load{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        //要特别注意你替换的方法到底是哪个性质的方法(实例方法:Class class = [self class]; 类方法:Class class = object_getClass((id)self);)
        //类方法的写法
        Class class = object_getClass((id)self);
        // 获取系统的selector
        SEL   originalSelector = @selector(systemFontOfSize:);
        SEL   originalSelector1 = @selector(fontWithName:size:);
        // 自己要交换的selector
        SEL   swizzledSelector = @selector(tc_systemFontOfSize:);
        SEL   swizzledSelector1 = @selector(tc_fontWithName:size:);
        // 两个方法的地址
        Method originalMethod = class_getClassMethod(class, originalSelector);
        Method swizzledMethod = class_getClassMethod(class, swizzledSelector);
        Method originalMethod1 = class_getClassMethod(class, originalSelector1);
        Method swizzledMethod1 = class_getClassMethod(class, swizzledSelector1);
        //  动态添加方法
        BOOL didAddMethod =
        class_addMethod(class,
                        originalSelector,
                        method_getImplementation(swizzledMethod),
                        method_getTypeEncoding(swizzledMethod));
        BOOL didAddMethod1 =
        class_addMethod(class,
                        originalSelector1,
                        method_getImplementation(swizzledMethod1),
                        method_getTypeEncoding(swizzledMethod1));
        
        if (didAddMethod) {
            class_replaceMethod(class,
                                swizzledSelector,
                                method_getImplementation(originalMethod),
                                method_getTypeEncoding(originalMethod));
        } else {
            method_exchangeImplementations(originalMethod, swizzledMethod);
        }
        if (didAddMethod1) {
            class_replaceMethod(class,
                                swizzledSelector1,
                                method_getImplementation(originalMethod1),
                                method_getTypeEncoding(originalMethod1));
        } else {
            method_exchangeImplementations(originalMethod1, swizzledMethod1);
        }
    });
}

+ (UIFont *)tc_systemFontOfSize:(CGFloat)fontSize {
    UIFont *newFont = nil;
    newFont = [UIFont tc_systemFontOfSize:fontSize * Scaling];
    return newFont;
}

+ (UIFont *)tc_fontWithName:(NSString *)fontName size:(CGFloat)fontSize {
    UIFont *newFont = nil;
    newFont = [UIFont tc_fontWithName:fontName size:fontSize * Scaling];
    return newFont;
}
@end

xib适配

#import "UILabel+ScaleAdapter.h"
#import <objc/runtime.h>
//UI设计图宽度
#define DesignWidth 414.0
//缩放比例
#define Scaling ((CGFloat)([UIScreen mainScreen].bounds.size.width / DesignWidth))

@implementation UILabel (ScaleAdapter)

// 利用runtime机制,在load方法中实现让 jx_awakeFromNib 和 awakeFromNib 方法交换
+ (void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        //要特别注意你替换的方法到底是哪个性质的方法(实例方法:Class class = [self class]; 类方法:Class class = object_getClass((id)self);)
        //类方法的写法
        Class class = [self class];
        // 获取系统的selector
        SEL   originalSelector = @selector(awakeFromNib);
        // 自己要交换的selector
        SEL   swizzledSelector = @selector(tc_awakeFromNib);
        // 两个方法的地址
        Method originalMethod = class_getInstanceMethod(class, originalSelector);
        Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
        //  动态添加方法
        BOOL didAddMethod =
        class_addMethod(class,
                        originalSelector,
                        method_getImplementation(swizzledMethod),
                        method_getTypeEncoding(swizzledMethod));
        
        if (didAddMethod) {
            class_replaceMethod(class,
                                swizzledSelector,
                                method_getImplementation(originalMethod),
                                method_getTypeEncoding(originalMethod));
        } else {
            method_exchangeImplementations(originalMethod, swizzledMethod);
        }
    });
}

- (void)tc_awakeFromNib {
    [self tc_awakeFromNib];
    self.font = [UIFont fontWithDescriptor:self.font.fontDescriptor size:self.font.pointSize * Scaling];
}
@end

注意:

关于宏定义中的DesignWidth,由于每人情况不同,请自行修改使用
[git链接]https://github.com/tcgitios/UILabelScaleAdapter

相关文章

网友评论

      本文标题:iOS字体大小的自动适配(代码&xib)

      本文链接:https://www.haomeiwen.com/subject/xscmhctx.html