带有TypographyKit的iOS中的动态类型

动态类型是iOS 7中引入的功能,允许用户更改跨iOS使用的默认字体大小。 它主要用于支持视觉障碍的用户,但实际上,出于各种原因,许多iOS用户只是更喜欢较小/较大的阅读尺寸。 可以从“显示和亮度”->“文本大小”中的“设置”应用程序更新,也可以从“常规”->“辅助功能”->“大文本”中更新设置。 如果使用前一种设置,则只有七个字体大小可供选择,而在后一部分中,有一个“较大的可访问性大小”开关,如果启用,则允许用户从另外五个较大的字体大小中进行选择。

没有开发人员的额外努力,App Store中的应用程序不会自动支持动态类型(与Android不同)。 在iOS 7中,Apple提供了六个UIFontTextStyles,即为屏幕上的每个标签分配一个文本样式,例如标题文本或正文文本,这将使应用程序开发人员可以按如下方式检索该文本样式的首选字体:

  UIFont.preferredFont(forTextStyle:.body) 

当用户调整“设置”应用中的字体大小滑块时,此方法返回的字体的磅值会相应更新。

在iOS 7时代,实现动态类型具有挑战性,因为要求应用程序开发人员将每个显示文本的UIKit元素分类为可用的UIFontTextStyle类别之一,以便检索该类别的首选字体。 此外,返回的首选字体将是系统字体,即Helvetica Neue Light(在9之前的iOS版本上;在iOS 9及更高版本中默认为旧金山),这意味着开发人员在支持动态类型时无法使用自定义字体(更多信息请参见稍后)。 由于这些原因,App Store中的应用程序通常不支持动态类型。

如果用户在“设置”应用程序中更新了字体大小首选项,则已经打开且支持动态类型的应用程序通常直到用户关闭并重新启动后才会更新(取决于对UIFont.preferredFont(forTextStyle: )。 每次用户使用“设置”应用程序中的滑块更新“动态类型”首选项时,都会更新属性UIApplication.shared.preferredContentSizeCategory的值,并返回新的UIContentSizeCategory值,即滑块上的每个槽口都对应一个UIContentSizeCategory值。

为了更新应用程序的字体大小而不必关闭并重新打开应用程序,开发人员可以使用NotificationCenter观察(UIContentSizeCategory)didChangeNotification,然后调用UIFont.preferredFont(forTextStyle :),该字体将返回具有更新大小的字体每个UIKit元素都会在屏幕上显示文本。 实际上,在每个UIViewController中观察此通知并以编程方式在屏幕上更新每个文本UIKit元素通常会导致UIViewController Controller肿,其中包含许多其他代码来支持动态类型。

出于上述原因,创建了TypographyKit。 TypographyKit允许应用程序使用自定义字体,同时支持来自iOS 9+的Dynamic Type,而无需大量额外代码。 如果使用Cocoapods,可以通过将以下行添加到项目Podfile中,然后运行“ pod install”命令来将TypographyKit合并到您的Xcode项目中:

pod "TypographyKit" 

对于那些使用迦太基的人,可以通过在项目的Cartfile中添加以下行,运行“迦太基更新–平台iOS”来构建框架,然后手动为相关Xcode项目目标链接构建框架,从而安装TypographyKit:

 github "rwbutler/TypographyKit" 

下一步是将TypographyKit配置文件添加到您的项目中(请确保将其添加到“副本捆绑资源”构建阶段)。 该文件可以采用属性列表或JSON格式,并分别命名为TypographyKit.plist或TypographyKit.json。 TypographyKit配置指定在应用程序中使用的印刷样式(即UIFontTextStyles)以及每种样式的外观。 它还指定字体应如何随着UIContentSizeCategory的更改而缩放:

  { 
  “ typography-colors”:{ 
  “ background”:“较淡的宝蓝色”, 
  “ gold”:“#FFAB01”, 
  “宝蓝色”:“#08224C”, 
  “ text”:“ gold” 
  }, 
  “印刷工具包”:{ 
  “最小点数”:10, 
  “最大点数”:100, 
  “点步长”:2 
  “点步乘数”:1 
  }, 
  “ ui-font-text-styles”:{ 
  “标题”:{ 
  “ font-name”:“ Avenir-Medium”, 
  “点大小”:36, 
  “ text-color”:“文本”, 
  “字母大小写”:“常规” 
  }, 
  “段落”:{ 
  “ font-name”:“ Avenir-Medium”, 
  “点大小”:16 
  “ text-color”:“文本”, 
  “字母大小写”:“常规” 
  } 
  } 
  } 

TypographyKit配置文件可以远程托管,因此可以认为几乎类似于应用程序的CSS文件。

“印刷工具包”部分指定如何随UIContentSizeCategory的更改缩放字体,默认情况是UIContentSizeCategory的每次增加都会增加两点(即,“设置”中文本大小滑块上的每个槽口)。 您可以在此处指定最大和/或最小磅值,以防止字体缩放到您定义的明智值以上/以下。

“ ui-font-text-styles”部分指定了您应用的字体样式。 对于每种样式,“字体名称”(可以是系统字体或自定义字体)和该字体的默认“磅值”,即“设置”中的“文字大小”滑块设置为中间凹口时的文字大小(等于UIContentSizeCategory.large)应该被指定。 (可选)可以将文本样式的颜色和字母大小写定义为字体样式的一部分,以使该样式可以由Avenir-Medium字体组成,默认字体为蓝色,大写为36点。

这里需要注意几件事-“字体名称”的值应该是字体的PostScript名称,如果不确定,可以使用“字体书”应用程序检索该字体。 如果使用自定义字体,则必须在使用之前将该字体定义为应用程序“ Info.plist”中“应用程序提供的字体”下的一部分,例如,

   UIAppFonts  
   
   MyCustomFont.otf  
   

“文本颜色”的值可以是简单的颜色值,例如“蓝色”,以#开头的十六进制值(例如“#08224C”)或RGB颜色值(颜色分量在0-255范围内),例如“ rgb(255,255,255)’。 建议您在配置的“印刷颜色”部分中分配一种颜色,以用作印刷样式的一部分。 优点包括:

  • 可以通过UIColor的扩展程序以编程方式使用相同的颜色,以便在整个应用程序中一致地应用相同的颜色阴影:
 extension UIColor { 
static let textColor: UIColor = TypographyKit.colors["text-color"]!
}
  • iOS 11引入了UIColor(named :)初始化程序,允许实例化资产目录中定义的颜色。 TypographyKit可以将此功能回填到iOS 9,前提是该颜色也在TypographyKit.json中定义,并且UIColor扩展名(如上)用于访问该颜色。 在iOS 11上,它将调用UIColor(named :),而在先前的iOS版本上,请使用TypographyKit.json中的颜色定义。
  • TypographyKit的调色板能够生成用于Interface Builder的调色板,以便在IB中编辑Storyboard和XIB时,也可以选择配置中定义的颜色。
  • 如果TypographyKit远程托管,则您的应用的调色板可以在发布后进行更新。
  • 支持递归颜色定义,以便您可以在TypographyKit.json中将文本颜色设置为“ gold”,其中在配置中将金定义为“#FFAB01”。 对于开发人员而言,这比简单地设置“ text-color”:“#FFAB01”更容易阅读。

有关颜色配置的更多信息,请参见TypographyKit中的博客文章“远程配置的调色板”。

可能适用于您的排版样式的字母大写包括:

  • 常规(文本保持不变-这是默认设置)
  • 大写(每个单词的首字母大写)
  • 烤肉串(带连字符的单词)
  • 小写(小写)
  • 小写驼峰(每个单词以小写字母开头的大写驼峰,例如lowerCamelCase)
  • 宏(带有下划线的单词大写,例如MACRO_CASE)
  • 蛇(小写,单词之间的空格已删除)
  • 大写(大写)
  • 大写字母(每个单词都以大写字母开头的大写字母,例如UpperCamelCase)

定义了应用程序的字体样式后,可以通过将名为“ fontTextStyleName”的字符串类型的键路径值设置为“您在TypographyKit配置文件中定义的样式。 可以在Interface Builder的“实用程序”部分的Identity Inspector中找到它(请参见下文)。 TypographyKit示例应用程序提供了一个示例。

正确设置键路径后,您的UIKit元素将响应UIContentSizeCategory中的更改,而无需任何其他代码。

许多应用程序开发人员与设计团队一起工作,他们通常热衷于通过一致使用颜色和印刷样式来支持应用程序的可访问性并在整个应用程序中实现视觉一致性,但是将仅用于系统字体的字体和文本类别的数量限制到很小在支持动态类型时,数字通常是破坏交易的因素。

Apple意识到了这一点,因此在iOS 9中引入了四个新的UIFontTextStyle类,而largeTitle样式在稍后的iOS 11中引入:

  • 机身(iOS7)
  • 标注(iOS9)
  • caption1(iOS7)
  • caption2(iOS7)
  • 脚注(iOS7)
  • 标题(iOS7)
  • 副标题(iOS7)
  • largeTitle(iOS11)
  • title1(iOS9)
  • title2(iOS9)
  • title3(iOS9)

事实证明,这仍然是相当有限的,因为即使开发人员能够将应用程序中使用的文本样式的数量限制为11种,以上分类也不适合开发人员的应用程序。 例如,开发人员希望将相同的文本样式一致地应用于应用程序中的每个按钮。 应该把它塞进caption2 UIFontTextStyle吗? 11种文字样式是否足以覆盖应用程序中的每种印刷样式?

TypographyKit通过允许开发人员定义自己的UIFontTextStyles集来解决此问题。 在上面的TypographyKit.json示例中,即使上面的UIFontTextStyles列表中没有这种样式,也定义了名为“ paragraph”的样式(作为“ ui-font-text-styles”部分的一部分)。 只要在TypographyKit配置中存在样式的定义,开发人员就可以使用现有的UIFontTextStyles或通过在UIFontTextStyle上创建扩展来创建新的自定义样式:

 扩展UIFontTextStyle { 
静态让段落= UIFontTextStyle(rawValue:“段落”)
}

但是,建议将应用程序中使用的UIFontTextStyles的数量保持为最少,以使该应用程序在视觉上尽可能一致,因为不强制执行一致性的应用程序会导致UI混乱或混乱。

根据TypographyKit配置中定义的设置,自定义UIFontTextStyles的行为与文本缩放时提供的标准行为完全相同。

苹果在iOS 10中进行的另一项改进是引入了由UILabel,UITextField和UITextView实现的UIContentSizeCategoryAdjusting协议,该协议包含以下属性:

var adjustsFontForContentSizeCategory: Bool

此属性允许实现UIKit元素的文本随UIContentSizeCategory的更改而自动调整,并且可以通过选中“自动调整字体”复选框在情节提要中进行设置。 如果将UIKit元素设置为使用Attributed而非纯文本,则此属性不起作用。 另一个大的警告是,在使用自定义字体的情况下,此属性不起作用。

在使用TypographyKit的情况下,这些控件甚至可以在包括UIButtons的iOS 9中进行调整,并且可以与属性文本一起使用(尽管当前对这种支持的支持有限,并且计划在将来进行扩展)。

苹果对Dynamic Type实施的最大改进是在iOS 11中引入了UIFontMetrics类。这使开发人员可以使用以下方法来获取包含自定义字体的字体的缩放版本:

 func scaledFont(for font: UIFont) -> UIFont 

通过提供要缩放的字体,此方法使用请求UIFont.preferredFont(forTextStyle :)的系统字体,将返回相同的字体,并根据用户的首选UIContentSizeCategory进行缩放,并使用相同的变换。 在每个UIContentSizeCategory步骤中,旧金山的字体大小可以作为《人机界面指南》的一部分找到。

总之,TypographyKit为开发人员提供了以下好处:

  • 在无法使用UIFontMetrics的iOS 9+上使用自定义字体支持动态类型。
  • 动态类型缩放可以限制在最小和/或最大字体大小。
  • 支持动态类型可能会使UIViewController大量膨胀-TypographyKit提供了通过配置完全支持动态类型的选项(零附加代码)。 在以编程方式实施的地方提供了便利的方法。
  • iOS 10中的UIContentSizeCategoryAdjusting不适用于自定义字体,迫使开发人员返回NotificationCenter观察,而TypographyKit将其返回iOS 9。
  • 增强应用程序的版式和调色板的视觉一致性,可以选择将字母大小写作为版式样式的一部分,以增强应用程序的版式和调色板的视觉一致性。
  • TypographyKit配置可以远程托管,为您的应用程序提供类似于CSS的功能。
  • 响应iOS 9+上UIContentSizeCategory的更改,包括对UIButton和NSAttributedString的支持,UIKit当前不支持这些支持。
  • 与您的设计团队定义自定义UIFontTextStyles,以提出一组最适合您的应用程序的文本样式。
  • 允许在类似于Android的colors.xml的单个位置中定义颜色,并以编程方式以及在使用Palette的Interface Builder中使用颜色。
  • 适用于iOS 11之前的UIColor(named :)的Shim。

可以在GitHub上找到有关TypographyKit的更多信息。

参考文献

Apple开发人员文档(特别是向您的应用添加自定义字体,didChangeNotification,preferredContentSizeCategory和UIContentSizeCategory)

苹果开发人员人机界面指南

TypographyKit中的远程配置调色板