美文网首页iOS基础知识补充
UILabel的字体大小根据机型自动适配

UILabel的字体大小根据机型自动适配

作者: 施忆 | 来源:发表于2018-04-03 21:32 被阅读197次

    1、引言

    由于公司产品经理提出的需求,说不同机型下的字体变化不怎么明显,尤其是iPhone 5s,字体比较大,固定的控件大小、位置就显得比较拥挤;其他机型则还好,显示比较正常。

    2、效果

    图1

    3、方案

    1、分纯代码和XIB/SB

    1.纯代码

    //初始化
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 200, 25)];
        label.center = CGPointMake(self.view.frame.size.width/2, self.view.frame.size.height/2-100);
        CGFloat multiple = [self fontMultiple];
        label.font = [UIFont systemFontOfSize:17.0*multiple];
        label.text = @"①自动适配文字大小";
        label.textAlignment = NSTextAlignmentCenter;
        label.textColor = [UIColor blackColor];
        [self.view addSubview:label];
    }
    //倍数
    - (CGFloat)fontMultiple
    {
        CGFloat width = [UIScreen mainScreen].bounds.size.width;
        if (width == 320) {
            return FONT_IPHONE_5S;//0.7
        }
        else if (width == 375) {
            return FONT_IPHONE_6;//1.0
        }
        else if (width == 414) {
            return FONT_IPHONE_6P;//1.3
        }
        else {
            return FONT_IPHONE_OTHER;//1.1
        }
    }
    

    2.XIB/SB


    图2
    - (void)viewWillLayoutSubviews
    {
        [super viewWillLayoutSubviews];
    
        if (IS_IPHONE_5) {
            _textLabel.font = [UIFont systemFontOfSize:12];
        }
        //XIB/SB中默认设置就是6和6p的文字大小
        if (IS_iPhoneX) {
            _textLabel.font = [UIFont systemFontOfSize:13];
        }
    }
    
    2、使用分类+runtime交换方法实现

    关于runtime的具体实战请跳转:传送门
    1.UIFont

    + (void)load
    {
        [self exchangeMethod:@selector(systemFontOfSize:) with:@selector(SY_systemFontOfSize:)];
    }
    
    + (UIFont *)SY_systemFontOfSize:(CGFloat)fontSize
    {
        //这里并不是循环调用,+load里已经把这方法与系统的方法交换了,因此这里调用的是系统方法
        CGFloat multiple = [self fontMultiple];
        UIFont *font = [self SY_systemFontOfSize:fontSize*multiple];
        return font;
    }
    
    + (CGFloat)fontMultiple
    {
        CGFloat width = [UIScreen mainScreen].bounds.size.width;
        if (width == 320) {
            return FONT_IPHONE_5S;
        }
        else if (width == 375) {
            return FONT_IPHONE_6;
        }
        else if (width == 414) {
            return FONT_IPHONE_6P;
        }
        else {
            return FONT_IPHONE_OTHER;
        }
    }
    
    + (BOOL)exchangeMethod:(SEL)systemSel with:(SEL)newSel
    {
        Class class = object_getClass(self);
        Method originalMethod = class_getInstanceMethod(class, systemSel);
        Method newMethod = class_getInstanceMethod(class, newSel);
        if (!originalMethod || !newMethod) return NO;
        method_exchangeImplementations(originalMethod, newMethod);
        return YES;
    }
    

    2.UILabel

    + (void)load
    {
        [[self class] exchangeMethod:@selector(initWithCoder:) with:@selector(SY_initWithCoder:)];
    }
    
    - (id)SY_initWithCoder:(NSCoder *)coder
    {
        [self SY_initWithCoder:coder];
        
        CGFloat fontSize = self.font.pointSize;
        self.font = [UIFont systemFontOfSize: fontSize];
        
        return self;
    }
    
    + (BOOL)exchangeMethod:(SEL)systemSel with:(SEL)newSel
    {
        Method originalMethod = class_getInstanceMethod(self, systemSel);
        Method newMethod = class_getInstanceMethod(self, newSel);
        if (!originalMethod || !newMethod) return NO;
        
        class_addMethod(self,
                        systemSel,
                        class_getMethodImplementation(self, systemSel),
                        method_getTypeEncoding(originalMethod));
        class_addMethod(self,
                        newSel,
                        class_getMethodImplementation(self, newSel),
                        method_getTypeEncoding(newMethod));
        
        method_exchangeImplementations(class_getInstanceMethod(self, systemSel),
                                       class_getInstanceMethod(self, newSel));
        return YES;
    }
    
    3、两种方案的对比

    虽然实现的结果都一样,但很明显,第二种方案是最好的,因为只要在项目中加入这两个分类,就可以实现所有的(无论纯代码还是XIB/SB)label文字根据屏幕自动适配。第一种方案,在纯代码下可以使用,但XIB文件很多的话,就非常的麻烦。

    4、Demo下载

    gitub下载链接

    相关文章

      网友评论

        本文标题:UILabel的字体大小根据机型自动适配

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