引子
今天看了一篇关于 Autolayout 的使用技巧介绍文章《高级 iOS 开发工程师应该掌握的自动布局技术》。其中里面谈到使用一种 Xcode 自带的界面层级检测工具 Accessibility Inspector,同时这个工具也可以用来实时动态改变支持了Dynamic type的 label 所显示的字体大小,这其中当然有一些限制啦 O(∩_∩)O,容我一一道来~。
一、Xcode 自带的界面层级检测工具 Accessibility Inspector 真容
这就是Accessibility Inspector的操作界面啦以下启动该工具的步骤:
二、动态字体 Dynamic type 是什么?
Dynamic type 动态类型字体 早在 iOS 7 时候就已经被引入,作为为一种便捷开发方式而将字体的细节(如:字体类型,大小,重量及字距)抽象成一系列的预设定字体样式类别叫做文本风格(text styles)。
其中 iOS 7 的 Text Styles 包括:
- UIFontTextStyleHeadline
- UIFontTextStyleSubheadline
- UIFontTextStyleBody
- UIFontTextStyleFootnote
- UIFontTextStyleCaption1
- UIFontTextStyleCaption2
iOS 9 之后,苹果又添加了4中新的 Text Styles:
- UIFontTextStyleCallout
- UIFontTextStyleTitle1
- UIFontTextStyleTitle2
- UIFontTextStyleTitle3
而如果你在 Xcode 8 上的话,选中一个 Lable 的 Attributed Inspector -> font,即可看到所有的先在支持的Text Styles:
所有 Text Styles 对应的样式如下图:
苹果设计的这些Text Styles 都有特定的使用场景。其中最常用的是UIFontTextStyleBody正文样式,苹果原生的应用内所有显示正文的地方都选用该Text Style,如在 mail app 正文文本和 TabelViewCell 的主文本显示等。
通过代码创建自定 textstyle 的字体,可以使用+preferredFontForTextStyle:
类方法,如下:
UIFont *myFont = [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
三、为什么使用动态字体 Dynamic type
使用Dynamic type的优势是,会根据系统的字体大小偏好设定而自动更新对应的字体大小值(当然ios9或之前这些都是需要手动去处理的,蛋疼的过程就不详细描述啦<( ̄3 ̄)> !)
Dynamic type 允许用户自定义文本大小从而满足app的需要。不过仅有采用Dynamic Type的app才能响应文本的改变,可能只有一小部分第三方应用使用了该功能。在 iPhone 的短信消息中,如果用户喜欢大一点的字体,通过在设置中进行设置后,我们将看到消息界面会有所变化,字体变大了,消息气泡和输入文本也变大了。日历和其他一些地方也具备类似的功能。
情况如下图:
-
按照系统设定的默认大小
-
当选择大字体值时
是不是一个很棒棒的功能呢?那问题来了,在 iPhone 中怎样选择这些字体大小呢?
步骤是:
界面设置图iPhone的设置->通用->辅助功能->更大字体
四、怎么使用动态字体 Dynamic type
1. iOS 10 之前:
这个以后再分写一篇吧,其实如下这篇文字描述得挺详细了,可以用于实战参考。
iOS 7 Tutorial Series: Dynamic Type
大概流程:
1.注册一个DynamicType的消息通知:UIContentSizeCategoryDidChangeNotification
[[NSNotificationCenter defaultCenter]
addObserver : self
selector : @selector(userTextSizeDidChange)
name : UIContentSizeCategoryDidChangeNotification
object : nil];
2.当系统字体大小改变时,在接收通知的实现方法里处理嵌入到视图了的labels, text fields 和 text views等控件字体大小的适配工作(又是一个蛋疼的搬砖工作(>_<))。如
self.textLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
//这里调用setNeedsLayout做一个需要重新布局的标记,在下一个draw周期(60Hz)自动重绘
[self.view setNeedsLayout];
3.最后在layoutSubview或者viewDidLayoutSubview里面更新textLabel的frame
2. iOS 10或以上:
- 通过代码设置的话就两步即可:
// 1. 设置字体大小 self.demoLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody]; // 2. 允许调整 self.demoLabel.adjustsFontForContentSizeCategory = YES;
- 这个属性
adjustsFontForContentSizeCategory
的设置在 Xcode 8.3 开始即可在 xib 或 sb 中设置,对应的位置是:
也就是说,结合上述在 xib 中可选对应 text Style 方式,可这正一行代码都不用写就可以支持 Dynamic Type了。ヽ(✿゚▽゚)ノ好耶~
了解以上操作后,回到正题 Accessibility Inspector 有什么用?
五、Accessibility Inspector 的使用。
支持了 Dynamic Type之后,Accessibility Inspector 的使用“终于”派上用场了,那就是,在另外一个界面动态设置字体,实际就是方便测试而已,免得在 App 与 设置界面间来回切换。。。
运行程序后,在 Xcode 上又有两个入地方可以进入View UI Hierarchy是不是感觉被坑了~哈哈。其实,Accessibility Inspector 更有用的功能能应该是可以查看界面布局的层级关系,可惜的是它只会通过过 text 的样式进行描述,所以如果需要查看界面布局层级关系等信息,都是通过 Reveal 和 Xcode 自带的 View UI Hierarchy
点击上层按钮后弹出的对话框,选择 View UI Hierarchy
如下是 iOS 10 Demo 演示 Dynamic type
-
支持了 Dynamic Type
-
启动 Accessibility Inspector ,点击顶部导航条Xcode->Open Develop Tool->Accessibility Inspector->target切换至模拟器->选择设置标签,就可以看到修改字体大小的滑块了。这个时候滑动滑块就能看到我们的 label 字体在实时地改变。如果我们连接了 iPhone ,我们也可以将target切换至我们的 iPhone 。
-
移动滑块后实时效果
Ref:
Developing for iOS 9: Supporting Dynamic Type and Responding to User Changes