前言

之前做过很多项目都没考虑过字体适配问题。相信绝大多数人在做项目时,都没仔细去考虑这件事。一般都是根据UI出的图做个估算,有耐心的估计会自己拿工具测量下。如今,考虑到iPhone机型的多样性,UI设计师不可能针对每一款iPhone的屏幕出一套UI图。一般而言,都是基于5s的标准出UI。当我们在设置字体时,往往都是基于UI并且针对不同的屏幕字体也都是绝对的。那么问题来了,细心的同学可能会注意到,相同大小的字体在5s或6上也许差别不大,但在6p上字体有缩小的现象,其原因由分辨率导致。
在6出来不久,曾看过有关适配的文章,其中关于iPhone尺寸规格如下:

设备 对角线 逻辑分辨率 scale Factor 设备分辨率 PPI
3GS 2.4inch 4.5inch 3.5inch 320x480 @1x 320x480 163
4(s) 2.31inch 4.5inch 3.5inch 320x480 @2x 640x960 326
5c 2.33inch 4.90inch 4inch 320x568 @2x 640x1136 326
5(s) 2.31inch 4.87inch 4inch 320x568 @2x 640x1136 326
6 2.64inch 5.44inch 4.7inch 375x667 @2x 750x1334 326
6p 3.06inch 6.22inch 5.5inch 414x736 @3x 1242x2208 401

从iPhone3GS/iPhone4(s)过渡到iPhone5(s)时,在逻辑上宽度不变高度稍高,之前旧的素材和布局通过AutoresizingFlexible简单适配即可运行得很好,但由于高宽比增大,上下两端出现黑粗边(典型如LaunchImage)。从分辨率的角度来看,除了需要提供LaunchImage这种满屏图,其他基本沿用二倍图(@2x);从屏幕尺寸角度来看,需要对纵向排版略加调整。
从iPhone5(s)发展到iPhone6(+),由于高宽比保持不变,iOS对图标、图片、字体进行等比放大自适应,清晰度会有所降低。同时,绝对坐标布局会导致在大屏下出现偏左偏上的问题。从分辨率的角度来看,iPhone6沿用二倍图(@2x),但需为iPhone6+提供更高的三倍图(@3x);从屏幕尺寸角度来看,需要重新对UI元素尺寸和布局进行适配,以期视觉协调。

字体适配

以上属于科普类的东西,下面来点实际的。

关于字体适配有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

当然,这并不是最终也不是最好的适配方案。个人觉得根据PPI适配字体,限于经历有限只能研究到这。
欢迎纠错,有什么好的字体适配方案也可以在下方评论进行探讨。

Demo地址:https://github.com/keleyundou/AdaptiveFontDemo

关于字体适配的那些事相关推荐

  1. Android面试题-解决字体适配

    源码分析相关面试题 Volley源码分析 注解框架实现原理 okhttp3.0源码分析 onSaveInstanceState源码分析 Activity相关面试题 保存Activity的状态 acti ...

  2. iOS 字体适配的几种方法总结

    在iOS开发中,有些公司对字体也有适配要求,为了让字体美观,所以在不同尺寸的屏幕上字体大小也要做到适配. 自己总结了几种方法供大家参考. 方法一:用宏定义适配字体大小(根据屏幕尺寸判断) //宏定义 ...

  3. vue-vant项目字体以及组件字体适配

    1. 页面中字体适配的方法: 新建一个rem.js文件: const baseSize = 32 function setRem () {const scale = document.document ...

  4. 聊一聊Android中的字体适配

    今日科技快讯 据The Verge报道,就在发射进入轨道的第二天,SpaceX的"载人龙飞船"(Crew Dragon)与国际空间站实现对接,这是该公司目前测试飞行的关键部分.当& ...

  5. React Native字体适配解决方案

    源码已上传 Github: react-native-app-font "怎么又是字体,老常的话题现在还拿出来说.关于字体适配的解决方式网上一搜几十篇!".看到标题的烙铁心里一万个 ...

  6. 微信iOS多设备多字体适配方案总结

    一.背景 2014下半年,微信iOS版先后适配iPad, iPhone6/6plus.随着这些大屏设备的登场,部分用户觉得微信的字体太小,但也有很多用户不喜欢太大的字体.为了满足不同用户的需求,我们做 ...

  7. ui设计移动端字体适配_超全面的移动端UI 设计规范整理汇总

    很多新人在开始做移动端UI设计的时候,往往对界面的一些尺寸规范不是十分清楚,很多时候都是凭借自己的感觉和经验去绘制界面,心里并没有一个清晰的概念,导致做出来的页面总是不那么尽如人意.本文整理汇总了一些 ...

  8. ui设计移动端字体适配_移动端UI设计规范全方位汇总(附演示PPT下载)

    很多新人在开始做移动端UI设计的时候,往往对界面的一些尺寸规范不是十分清楚,对做UI设计的基础概念也没有清晰的认识,很多时候都是凭借自己的感觉和经验去绘制界面,心里并没有一个清晰的概念,导致做出来的页 ...

  9. ui设计移动端字体适配_移动端界面设计之尺寸篇(更新)

    先来看看各种iPhone的尺寸和分辨率,这张图写的很清楚. 设备名称 屏幕尺寸 PPI Asset 竖屏点(point) 竖屏分辨率(px) iPhone X 5.8 in 458 @3x 375 x ...

最新文章

  1. php v9 分页静态,PHPCMS V9自定义栏目伪静态实现方法(列表页/分页/内容页)
  2. 说说今年网络安全的威胁和趋势
  3. holer实现外网访问内网数据库
  4. 编程思想:面向对象和面向过程
  5. 【BZOJ1923】[Sdoi2010]外星千足虫 高斯消元
  6. A站、B站、C站、D站、E站、F站、G站、H站、I站、J站、K站、L站、M站、N站、O站、P站、Q站、R站、S站、T站、U站、V站、W站、X站、Y站、Z站都是什么网站?Q站是什么?
  7. 新浪、腾讯微博开放平台非标准oauth解析
  8. 揭秘 | Akuna工作体验大揭秘
  9. 计算机磁盘管理 移动硬盘创建盘符,电脑中插入移动硬盘后无法显示分区盘符如何解决...
  10. java两张png图片合成_java将两张图片合成
  11. js运算保留后面两位小数
  12. 论文阅读笔记:Unsupervised Feature Learning via Non-Parametric Instance Discrimination
  13. 《从程序猿到项目经理》读后感-直率
  14. mysql导入sql文件、数据库时报错ERROR: ASCII '\0' appeared in the statement
  15. 嵌入式Linux学习笔记(1-2)——vi编辑器
  16. 独立站的7大运营手法
  17. matlab稀疏矩阵方程,Matlab命令集——稀疏矩阵函数
  18. 【笔记篇】04电商供应链流程——之《实战供应链》
  19. U盘无法访问,文件或目录损坏无法读取
  20. 【方差分析】单因素分析与多因素分析

热门文章

  1. 有想法就去设计吧!——《好玩的好设计》读书笔记
  2. ubuntu 16安装asp.net
  3. 链式前向星存图(有图详解)
  4. html文本框回车符换行符,文本域中换行符的替换示例
  5. 笔记:辗转相除法原理
  6. 继滴滴之后,网约车遇行业大洗牌
  7. 油漆桶beta1.0
  8. mysql进入database_MySQL中关于数据库database的那些操作
  9. Linux学习 nfs协议
  10. 好消息|深圳市16条在建地铁,有3条将通车