iOS自定义字体(二):全局字体修改
2021-03-15 本文已影响0人
degulade
全局修改UIFont字体:(包括UILabel和UIButton、UITextField和UITextView的font字体,目前只对systemFontOfSize和boldSystemFontOfSize两种方法有效)
完整代码如下,复制添加到项目中即可使用,不明白的地方看代码注释即可:
UIFont+FontChange.h
//
// UIFont+FontChange.h
// degulade
//
// Created by degulade on 2021/3/15.
//
import <UIKit/UIKit.h>
/// 默认字体修改(systemFontOfSize、boldSystemFontOfSize、italicSystemFontOfSize)
@interface UIFont (FontChange)
@end
/// 修改UILabel和UIButton的lab字体,对xib有效(xib加粗暂时待优化)
@interface UILabel (FontChange)
@end
/// 修改UITextField和UITextView的lab字体,对xib有效(xib加粗暂时待优化)
@interface UITextField (FontChange)
@end
UIFont+FontChange.m
//
// UIFont+FontChange.m
// degulade
//
// Created by degulade on 2021/3/15.
//
// 自定义的正常字体
#define CustomFontName @"FZSJ-PIANPXHN"
// 自定义的粗字体
#define CustomBoldFontName @"AaKYTNon-CommercialUse"
#import "UIFont+FontChange.h"
#import <objc/runtime.h>
@implementation UIFont (FontChange)
+ (void)load {
// 线程安全
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Class class = [self class];
// 系统systemFontOfSize方法
Method systemMethod = class_getClassMethod(class, @selector(systemFontOfSize:));
// 自定义systemFontOfSize方法
Method swizzMethod = class_getClassMethod(class, @selector(my_systemFontOfSize:));
// 交换方法
method_exchangeImplementations(systemMethod, swizzMethod);
// boldSystemFontOfSize
Method systemMethod1 = class_getClassMethod(class, @selector(boldSystemFontOfSize:));
Method swizzMethod1 = class_getClassMethod(class, @selector(my_boldSystemFontOfSize:));
method_exchangeImplementations(systemMethod1, swizzMethod1);
// italicSystemFontOfSize
Method systemMethod2 = class_getClassMethod(class, @selector(italicSystemFontOfSize:));
Method swizzMethod2 = class_getClassMethod(class, @selector(my_italicSystemFontOfSize:));
method_exchangeImplementations(systemMethod2, swizzMethod2);
});
}
/// 自定义正常字体
/// @param size siz
+ (UIFont *)my_systemFontOfSize:(CGFloat)size {
[UIFont my_systemFontOfSize:size];
UIFont *font = [UIFont fontWithName:CustomFontName size:size];
if (font) {
return font;
}
// 字体缺失时防奔溃处理
return [UIFont systemFontOfSize:size];
}
/// 自定义加粗字体
/// @param size siz
+ (UIFont *)my_boldSystemFontOfSize:(CGFloat)size {
[UIFont my_boldSystemFontOfSize:size];
UIFont *font = [UIFont fontWithName:CustomBoldFontName size:size];
if (font) {
return font;
}
return [UIFont boldSystemFontOfSize:size];
}
+ (UIFont *)my_italicSystemFontOfSize:(CGFloat)size {
[UIFont my_italicSystemFontOfSize:size];
UIFont *font = [UIFont fontWithName:CustomFontName size:size];
if (font) {
return font;
}
return [UIFont italicSystemFontOfSize:size];
}
@end
@implementation UILabel (FontChange)
+ (void)load {
//方法交换应该被保证,在程序中只会执行一次
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
//获得viewController的生命周期方法的selector
SEL systemSel = @selector(willMoveToSuperview:);
//自己实现的将要被交换的方法的selector
SEL swizzSel = @selector(myWillMoveToSuperview:);
//两个方法的Method
Method systemMethod = class_getInstanceMethod([self class], systemSel);
Method swizzMethod = class_getInstanceMethod([self class], swizzSel);
//首先动态添加方法,实现是被交换的方法,返回值表示添加成功还是失败
BOOL isAdd = class_addMethod(self, systemSel, method_getImplementation(swizzMethod), method_getTypeEncoding(swizzMethod));
if (isAdd) {
//如果成功,说明类中不存在这个方法的实现
//将被交换方法的实现替换到这个并不存在的实现
class_replaceMethod(self, swizzSel, method_getImplementation(systemMethod), method_getTypeEncoding(systemMethod));
} else {
//否则,交换两个方法的实现
method_exchangeImplementations(systemMethod, swizzMethod);
}
});
}
- (void)myWillMoveToSuperview:(UIView *)newSuperview {
[self myWillMoveToSuperview:newSuperview];
if (self) {
/// 移除某个tag的自定义字体样式
// if (self.tag == 10086) {
// self.font = [UIFont systemFontOfSize:self.font.pointSize];
// } else {
if ([UIFont fontNamesForFamilyName:CustomFontName])
self.font = [UIFont fontWithName:CustomFontName size:self.font.pointSize];
// }
}
}
@end
@implementation UITextField (FontChange)
+ (void)load {
//方法交换应该被保证,在程序中只会执行一次
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
//获得viewController的生命周期方法的selector
SEL systemSel = @selector(willMoveToSuperview:);
//自己实现的将要被交换的方法的selector
SEL swizzSel = @selector(myWillMoveToSuperview:);
//两个方法的Method
Method systemMethod = class_getInstanceMethod([self class], systemSel);
Method swizzMethod = class_getInstanceMethod([self class], swizzSel);
//首先动态添加方法,实现是被交换的方法,返回值表示添加成功还是失败
BOOL isAdd = class_addMethod(self, systemSel, method_getImplementation(swizzMethod), method_getTypeEncoding(swizzMethod));
if (isAdd) {
//如果成功,说明类中不存在这个方法的实现
//将被交换方法的实现替换到这个并不存在的实现
class_replaceMethod(self, swizzSel, method_getImplementation(systemMethod), method_getTypeEncoding(systemMethod));
} else {
//否则,交换两个方法的实现
method_exchangeImplementations(systemMethod, swizzMethod);
}
});
}
- (void)myWillMoveToSuperview:(UIView *)newSuperview {
[self myWillMoveToSuperview:newSuperview];
if (self) {
/// 移除某个tag的自定义字体样式
// if (self.tag == 10086) {
// self.font = [UIFont systemFontOfSize:self.font.pointSize];
// } else {
if ([UIFont fontNamesForFamilyName:CustomFontName])
self.font = [UIFont fontWithName:CustomFontName size:self.font.pointSize];
// }
}
}
@end