Skip to content

keleyundou/AdaptiveFontDemo

Folders and files

NameName
Last commit message
Last commit date

Latest commit

author
ColaBean
May 5, 2016
bd96639 · May 5, 2016

History

4 Commits
May 5, 2016
Jan 17, 2016
Jan 17, 2016
May 5, 2016

Repository files navigation

AdaptiveFontDemo

关于字体适配有2种方案。

  • 方案一: 设置一个大小区域范围,比如10~30pointSize的范围(pointSize为UIFont的一个CGFloat类型的属性),然后for循环降序遍历此范围设置一个临时的UIFont变量,根据此变量计算当前文本的大小,与当前UILabelheight作比较找出合适的字体。

#define ADAPTIVE__FONT_SIZE_MINIMUM_VALUE 20
#define ADAPTIVE_FONT_SIZE_MAXIMUM_VALUE 30

-(UIFont *) adjustFontSizeToFillItsContents
{
    NSString* text = self.text;
    
    for (int i = ADAPTIVE_FONT_SIZE_MAXIMUM_VALUE; i>ADAPTIVE__FONT_SIZE_MINIMUM_VALUE; i--) {
        
        UIFont *font = [UIFont fontWithName:self.font.fontName size:(CGFloat)i];
        NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:text attributes:@{NSFontAttributeName: font}];
        
        CGRect rectSize = [attributedText boundingRectWithSize:CGSizeMake(self.frame.size.width, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin context:nil];
        
        if (rectSize.size.height <= self.frame.size.height) {
            return [UIFont fontWithName:self.font.fontName size:(CGFloat)i];
            break;
        }
    }
    return self.font;
}

  • 方案二: 计算出一个scale重新设置UIFont,伪代码如下:
CGFloat scale = ([UIScreen mainScreen].bounds.size.width / 320);
NSLog(@"before : %.1f", [font pointSize]);
font = [UIFont fontWithName:[font fontName] size:fontSize * scale];
NSLog(@"after : %.1f", [font pointSize]);

既然需要重新设置UIFont,那么我们不可避免的要hookUIFont的类方法``fontWithName:size:做个函数交换的处理。 函数的交换我们需要用到runtime`机制。

void bd_exchageClassMethod(Class aClass, SEL oldSEL, SEL newSEL)
{
    Method oldClsMethod = class_getClassMethod(aClass, oldSEL);
    assert(oldClsMethod);
    Method newClsMethod = class_getClassMethod(aClass, newSEL);
    assert(newClsMethod);
    method_exchangeImplementations(oldClsMethod, newClsMethod);
}

然后,我们给UIFont创建一个Categroy文件,文件名为AdaptiveFont。在实现文件代码如下:

@implementation UIFont (AdaptiveFont)

+ (void)hook
{
    bd_exchageClassMethod([UIFont class], @selector(fontWithName:size:), @selector(hook_fontWithName:size:));
}

+ (UIFont *)hook_fontWithName:(NSString *)fontName size:(CGFloat)fontSize
{
    NSLog(@"before : %.1f", fontSize);
    CGFloat scale = ([UIScreen mainScreen].bounds.size.width / 320);
    NSLog(@"scale : %f", scale);
    UIFont *font = [self hook_fontWithName:fontName size:fontSize * scale];
    NSLog(@"after : %.1f", [font pointSize]);
    printf("<--------------------->\n");
    return font;
}

@end

接口文件暴漏相关方法如下:

@interface UIFont (AdaptiveFont)

+ (void)hook;
+ (UIFont *)hook_fontWithName:(NSString *)fontName size:(CGFloat)fontSize;

@end

相对比较而言,我还是倾向于方法二。方法一的前提条件是height要适配好,不能是绝对值,否效果。当然,方法二也一样,只不过height若是绝对值,会出现文字显示不全的问题。 在用法上,方法一只需调用adjustFontSizeToFillItsContents,而方法二需在application:didFinishLaunchingWithOptions:函数调用下hook

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published