美文网首页
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