代码改变世界

运用Runtime全局修改UILabel的默认字体

2016-03-08 23:01  蓝梦儿  阅读(854)  评论(0编辑  收藏  举报

 今天同事项目遇到一个问题,要修改所有UILabel的字体,我查了以下资料,推荐使用runtime机制替换掉UILabel的初始化方法,对label的字体进行默认设置。主要替换以下三个方法initWithFrame、init和xib用到的awakeFromNib,创建UILabel的类别代码如下:

.h

#import <UIKit/UIKit.h>

@interface UILabel (LabelDefaultFont)

@end

 

.m

#import "UILabel+LabelDefaultFont.h"
#import <objc/runtime.h>
@implementation UILabel (LabelDefaultFont)

+(void)load{

    static dispatch_once_t t;
    dispatch_once(&t, ^{
        Class class = [self class];
        // When swizzling a class method, use the following:
        //Class class = objc_getClass((id)self);
        
        //替换三个方法
        SEL selector_init = @selector(init);
        SEL selector_initWithFrame = @selector(initWithFrame:);
        SEL selector_awakeFromeNib = @selector(awakeFromNib);
        
        SEL selector_lfinit = @selector(LFinit);
        SEL selector_lfinitWithFrame = @selector(LFinitWithFrame:);
        SEL selector_lfawakeFromeNib = @selector(LFawakeFromNib);

        Method method_init = class_getInstanceMethod(class, selector_init);
        Method method_initWithFrame = class_getInstanceMethod(class, selector_initWithFrame);
        Method method_awakeFromeNib = class_getInstanceMethod(class, selector_awakeFromeNib);
        
        Method method_lfinit = class_getInstanceMethod(class, selector_lfinit);
        Method method_lfinitWithFrame = class_getInstanceMethod(class, selector_lfinitWithFrame);
        Method method_lfawakeFromeNib = class_getInstanceMethod(class, selector_lfawakeFromeNib);
        
        
        BOOL didAddMethod_init = class_addMethod(class, selector_init, method_getImplementation(method_lfinit), method_getTypeEncoding(method_lfinit));
        BOOL didAddMethod_initWithFrame = class_addMethod(class, selector_initWithFrame, method_getImplementation(method_lfinitWithFrame), method_getTypeEncoding(method_lfinitWithFrame));
        BOOL didAddMethod_awakeFromeNib = class_addMethod(class, selector_awakeFromeNib, method_getImplementation(method_lfawakeFromeNib), method_getTypeEncoding(method_lfawakeFromeNib));
        
        
        
        if (didAddMethod_init) {
            class_replaceMethod(class, selector_lfinit, method_getImplementation(method_init), method_getTypeEncoding(method_init));
        }else{
        
            method_exchangeImplementations(method_init, method_lfinit);
        }
        
        if (didAddMethod_initWithFrame) {
            class_replaceMethod(class, selector_lfinitWithFrame, method_getImplementation(method_initWithFrame), method_getTypeEncoding(method_initWithFrame));
        }else{
            
            method_exchangeImplementations(method_initWithFrame, method_lfinitWithFrame);
        }
        
        if (didAddMethod_awakeFromeNib) {
            class_replaceMethod(class, selector_lfawakeFromeNib, method_getImplementation(method_awakeFromeNib), method_getTypeEncoding(method_awakeFromeNib));
        }else{
            
            method_exchangeImplementations(method_awakeFromeNib, method_lfawakeFromeNib);
        }
        
        
        
    });
    
}
#pragma mark - 在以下方法中更换字体
-(instancetype)LFinit{
    id _self = [self LFinit];
    UIFont *font = [UIFont fontWithName:@"Copperplate-Bold" size:self.font.pointSize];
    if (font) {
        self.font = font;
    }
    return _self;
    
}
-(instancetype)LFinitWithFrame:(CGRect)frame{
    id _self = [self LFinitWithFrame:frame];
    UIFont *font = [UIFont fontWithName:@"Copperplate-Bold" size:self.font.pointSize];
    if (font) {
        self.font = font;
    }
    return _self;
}

-(void)LFawakeFromNib{
    [self LFawakeFromNib];
    UIFont *font = [UIFont fontWithName:@"Copperplate-Bold" size:self.font.pointSize];
    if (font) {
        self.font = font;
    }

}

@end

测试代码:

   UILabel *label1 = [[UILabel alloc]initWithFrame:CGRectMake(10, 180 + 20, 300, 30)];
//    label1.font = [UIFont fontWithName:@"Copperplate-Bold" size:17];
    label1.text = @"我是initwithframe创建的label1";
    [self.view addSubview:label1];
    
    UILabel *label2 = [[UILabel alloc]init];
    label2.frame = CGRectMake(10, CGRectGetMaxY(label1.frame) + 20, 300, 30);
    label2.text = @"我是init创建的label2";
    [self.view addSubview:label2];
    
    UILabel *label3 = [[UILabel alloc]init];
    label3.frame = CGRectMake(10, CGRectGetMaxY(label2.frame) + 20, 300, 30);
    label3.font = [UIFont systemFontOfSize:17];
    label3.text = @"我是init创建的label3,我设置系统默认字体";
    [self.view addSubview:label3];

    

效果:

代码链接:https://github.com/lilufeng/LabelFont_Runtime.git