Building Apps with Dynamic Type

2018/7/15 posted in  iOS

使用动态类型,人们可以选择自己喜欢的文本大小,iOS会根据需要自动切换字体。理解为什么动态类型很重要,以及在显示文本时如何支持它。了解iOS 11的新特性,掌握支持应用程序动态类型的框架和工具。

1.What is Dynamic Type?

Dynamic Type是一个允许用户在屏幕上自定义字体大小的功能。

屏幕快照 2018-12-13 下午6.37.58

对于视力有障碍的人来说区别很大,字体大之后就可以看到内容了。

2.What's New in iOS 11?

目标

  1. 字体要足够大
  2. 文字要完全,不允许截断
  3. UI还要依然美丽

使用说明和一些 API

  • 如何将字体和Dynamic type 一致
  • 适应更大的字体
  • Table views
  • Images

2.1如何将字体和Dynamic type 一致

通过文字样式TextStyle

  • 系统字体

    • xib 设置

    Artboard 2@3x

    • 代码设置
    UILabel * tip = [[UILabel alloc]init];
    [tip setFont:[UIFont preferredFontForTextStyle:UIFontTextStyleBody]];
    [tip setAdjustsFontForContentSizeCategory:YES];
  • 自定义字体
    上面说的是系统字体的时候可以跟随系统设置变大缩小,同样其他的自定义字体也可以通过UIFontMetrics达到一样的效果。

    UILabel * tip = [[UILabel alloc]init];
    [tip setFont:[[UIFontMetrics metricsForTextStyle:UIFontTextStyleBody] scaledFontForFont:customeFont]]
    [tip setAdjustsFontForContentSizeCategory:YES];

    Web Views实现跟随字体改变

    屏幕快照 2018-12-13 下午7.10.45

    当然这个只能适应于苹果设备,其他设备使用 rem

2.2 怎么适应大字体在屏幕上

  • 2.2.1 问题解答

    Q:如何解决文字变大后超出屏幕或者简单截断之后用户无法识别呢
    A:分为多行显示
    S:设置Label的 numberOflines = 0

    Q:之前设置的固定间距(比如设置LabelB的底部距离LabelA的底部40px),随着字体变大之后文本内容发生重叠

    Artboard 3@2x

    A1:设置LabelA的底部距离LabelB 的底部40px
    间距不变 但是是往不同方向方法
    修改后@2x

    A2:设置动态间距(iOS11以后可用)
    间距会随之变大
    屏幕快照 2018-12-14 上午11.06.14

    两种方案实现的效果不一样,如下所示。

    前后对比图@2x

  • 2.2.2 缩放值 Scaled Values

    缩放某个值,对于整体UI随着 large Text 来说有很重要的效果,会使整个UI看起来更协调。

    比如你之前是这么改变 y 值
    frame.origin.y +=40;

    现在你可以这么设置,constantVaule:40会根据系统设置而动态改变大小。

    frame.y += [[UIFontMetrics defaultMetrics] scaledValueForValue:40];

  • 2.2.3 并排文字的处理

    布局对比

    由上图可见,如果出现了文字变大的情况,如果不作任何处理会出现文字被截断的情况,直接影响了体验,如果只是简单的换行处理,会影响到美观,那么就可以垂直布置,横向沾满整个视图空间。

    通过函数[[UIApplication sharedApplication] preferredContentSizeCategory]orself.view.traitCollection.preferredContentSizeCategory获取用户的字体设置从UIContentSizeCategoryExtraSmallUIContentSizeCategoryExtraExtraLarge

    辅助设置的 largetext 的范围会有所区分会加上Accessibility比如UIContentSizeCategoryAccessibilityMedium

    所以在代码中就可以加上类似判断,判断当前的值是否大于某个界面改变的值,不同情形下布局结构不同。

    if (self.view.traitCollection.preferredContentSizeCategory > UIContentSizeCategoryLarge ) {
        //垂直布局
    }else{
    //并排布局
    }

2.3 Table views

如果你使用自带的 tableViewCell 那么就会自动布局,换行什么的完全不用你去担心。但是自定义 cell 的情况要自己去适配。

  • 2.3.1 Self-Sizing Table View Cells

    • 使用苹果默认设置的cell 样式

      • tableview 问每个 cell 提供高度
      • 提供一个预估的高度给那些在屏幕外的 cell

      如果必要就打开 self-sizing

      tableView.rowHeight = UITableViewAutomaticDimension
      tableView.estimatedRowHeight = 一个预估值
      

      如果有 sectionhead 或 sectionfooter

      self.tableView.estimatedSectionHeaderHeight = 20;
      self.tableView.sectionHeaderHeight = UITableViewAutomaticDimension;
      self.tableView.estimatedSectionFooterHeight = 20;
      self.tableView.sectionFooterHeight = UITableViewAutomaticDimension;
    • 使用自定义cell 样式并使用 autolayout

      如果你使用自定义 cell 并使用 autolayout 很容易就可以使用 self-sizing,你只要设置好约束条件,使他们来定义单元的大小,然后 autolayout 会给你找到合适的大小。

    • 使用自定义cell 样式不使用 autolayout

      • 重写 sizeThatFits 的方法返回正确的高度
      • 使用 contentView.bounds.size.width 限定宽度

2.4 Images

在放大文字内容的同时也要保证图片的可辨识度,而不是只是布局改变了,但是非常小不易于观察。

2.4.1 imageView
  • 使用 PDF 图片并且在 asset catalog 勾选Perserve Vector Data 或者不使用PDF图像,提供更大的版本@1x@2x@3x
  • imageView.adjustImageSizeForAceeseeibilityContentSizeCategory = Yes
  • xib勾选 imageview放大图片 Adjusts Image Size
2.4.2 长按放大 tabbarItem 的图片

屏幕快照 2018-12-14 下午3.47.06

  • 使用 PDF 图片并且在 asset catalog 勾选Perserve Vector Data并选择 single scale

    屏幕快照 2018-12-14 下午4.57.58

  • 如果不使用PDF图像,提供更大的版本并在xib 为bar Item设置 aceessibility 图片或者在代码设置barItem.largeContentSizeImage = largeImage;

Tips
  • 使用 PDF 图像可以保证@1x @2x @3x 使用同一个图像进行缩放。

  • Xcode -> Accessbility inspector(方便进行字体大小的调整)
    屏幕快照 2018-12-14 下午5.12.49