开发中我们常常遇到需要自定义字体的情况,苹果为我们提供了丰富的字体库,可在mac系统的字体册中查看,或者直接到系统资源库~/Font下查看,然而项目中如何高效利用呢。
我们可以通过以下代码查看系统字体库的样式:
// 遍历字体族
for (NSString * familyName in [UIFont familyNames]) {
// 字体族科
NSLog(@"familyName = %@",familyName);
for (NSString * fontName in [UIFont fontNamesForFamilyName:familyName])
{
// 族科下字体的样式
NSLog(@"%@",fontName);
}
}
我们经常看到一些有特色的项目可以一键切换系统字体,这是怎么做到的呢,如果一个个设置字体样式显然是不现实的,而且你如果这么写:
label3.font = [UIFont fontWithName:@"Americana Dreams Upright" size:30.0f];
你会发现并没有效果。
那么我们就可以用以下方式:
首先将你需要的字体类型引入工程。添加label的类扩展,然后添加以下两个方法
+ (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) {
if (self.tag == 10000) {
self.font = [UIFont systemFontOfSize:self.font.pointSize];
} else {
if ([UIFont fontNamesForFamilyName:CustomFontName])
self.font = [UIFont fontWithName:CustomFontName size:self.font.pointSize];
}
}
}
引入.h文件之后,你可以发现所有label包括button的字体样式已经是你想设置的。
然而问题又出来了,这时候如果我们需要部分字体格式不变呢?
这时候我们可以定义一个label的子类,实现下边的两个方法就可以了。
+ (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 ([UIFont fontNamesForFamilyName:CustomFontName])
self.font = [UIFont fontWithName:CustomFontName size:self.font.pointSize];
}
相关代码可到github下载:下载链接