ios TextKit中font相关

之前做模拟锁屏界面展示时间的时候,会发现其中的冒号会在ios7系统下变成方冒号,后来同事说可以借用UIFont的fontDescriptor来解决这个问题,而这个fontDescriptor是在苹果大大在介绍TextKit中提出,下面介绍下TextKit相关知识。

介绍

在ios7中引入了TextKit

Text Kit指的是UIKit框架中用于提供高质量排版服务的一些类和协议,它让程序能够存储,排版和显示文本信息,并支持排版所需要的所有特性,包括字距调整、连写、换行和对齐等。

如下图可以看到其所处位置(图片来自官方文档)


ios TextKit中font相关_第1张图片
TextKit位置

Text Kit主要的对象如下图(图片来自官方文档),
Text views对应UITextView类,用于展示文本内容;

在 TextKit 中,文本视图有两个目的:第一,它是文本系统用来绘制的视图。文本视图它自己并不会做任何绘制;它仅仅提供一个供其它类绘制的区域。作为视图层级机构中唯一的组件,第二个目的是处理所有的用户交互。具体来说,文本视图实现 UITextInput 的协议来处理键盘事件,它为用户提供了一种途径来设置一个插入点或选择文本。它并不对文本做任何实际上的改变,仅仅将这些改变请求转发给刚刚讨论的文本存储。

Text containers对应NSTextContainer类,用于定义文本置于哪一块,通常其是一个矩形区域,你也可以自定义成其他形状;
Layout manager对应NSLayoutManager类,用于对文本版面布局;
Text storage对应NSTextStorage类,其是NSMutableAttributedString的子类,用于存储文本内容,同时它也管理一系列NSLayoutManager对象,当文本的属性或字符发生变化的时候,通知NSLayoutManager对象重新布局和展示。


ios TextKit中font相关_第2张图片
TextKit主要对象

Text kit 常用的功能列举

1.对文字进行分页或多列排版
2.支持文字的换行、折叠和着色等处理
3.可以调整字与字之间的距离、行间距、文字大小、指定特定的字体
4.支持富文本编辑,可以自定义文字截断
5.支持凸版印刷效果(letterpress)
6.支持数据类型的检测(例如链接、附件等)

字体相关

  1. 系统原生字体
    一般没有特殊字体的要求,我们会用如下设定特定大小的文本
[UIFont systemFontOfSize:xx];

但是除此之外,可能也会需要加上格外的字体格式,可以用如下代码查看系统提供的字体格式有哪些,也可以访问ios字体预览

//系统提供所有字体家族名
[UIFont familyNames];
//每个字体家族名下各个字体名称
[[UIFont fontNamesForFamilyName:[[UIFont familyNames] objectAtIndex:section]]
//应用某个字体
UIFont *font = [UIFont fontWithName:@"HelveticaNeue-BoldItalic" size:20];
  1. 动态字体
    在设置->通用->辅助功能->更大字体,打开开关,点击进入可以调整字体大小,系统中字体会随之更改


    ios TextKit中font相关_第3张图片
    调整字体大小

    如果想要让你的应用中字体大小也能随着系统设置而改变,可以通过如下代码,建议动态字体和自动布局结合起来使用

UIFont *font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody];

但是如果程序在运行时,用户切换到设置里修改了字体,这是在切回程序,字体并不会自动跟着变。这时就需要我们自己来更新一下控件的字体了。
在系统字体修改时,系统会给运行中的程序发送UIContentSizeCategoryDidChangeNotification通知,我们只需要监听这个通知,并重新设置一下字体即可。

 [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(preferredContentSizeChanged:)
                                                 name:UIContentSizeCategoryDidChangeNotification
                                               object:nil];
-(void)preferredContentSizeChanged:(NSNotification *)notification{
  self.textView.font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
}
文本常量 用处
UIFontTextStyleHeadline headings
UIFontTextStyleBody body text
UIFontTextStyleSubheadline subheads
UIFontTextStyleFootnote footnotes
UIFontTextStyleCaption1 standard captions
UIFontTextStyleCaption2 alternate captions

3.字体描述符
即UIFontDescriptor,通过定义字体的一系列属性来创建UIFont对象,你可以从font descriptor获取到一个font对象,也可以从font对象中得到一个font descriptor,因此你可以通过更改font descriptor得到一个新的font对象。
你可以通过font descriptor获取到font family name下的所有font

UIFontDescriptor *helveticaNeueFamily = [UIFontDescriptor fontDescriptorWithFontAttributes:@{ UIFontDescriptorFamilyAttribute: @"Helvetica Neue" }];
NSArray *matches = [helveticaNeueFamily matchingFontDescriptorsWithMandatoryKeys: nil];

matches返回系统下所有与Helvetica Neue有关的字体
HelveticaNeue,
HelveticaNeue-Medium,
HelveticaNeue-Light,
HelveticaNeue-Thin
动态字体也可以用font descriptor来定义,还可以定义symbolic traits(bold,italic,expanded,condensed),具体如下

UIFontDescriptor *fontDescriptor = [UIFontDescriptor preferredFontDescriptorWithTextStyle: UIFontTextStyleBody];
UIFontDescriptor *boldFontDescriptor = [fontDescriptor fontDescriptorWithSymbolicTraits: UIFontDescriptorTraitBold];
UIFont *boldFont = [UIFont fontWithDescriptor: boldFontDescriptor size: 0.0];
//size为0,因为这边是动态字体,是随着系统设置变化

再介绍一个官方讲解应用font descriptor设置时间展示


ios TextKit中font相关_第4张图片
时间展示

我们需要的是下面的那种格式,代码如下

NSArray *timeFeatureSettings = @[
                                     @{
                                         UIFontFeatureTypeIdentifierKey: @(kNumberSpacingType),
                                         UIFontFeatureSelectorIdentifierKey: @(kProportionalNumbersSelector)
                                         },
                                     @{
                                         UIFontFeatureTypeIdentifierKey: @(kCharacterAlternativesType),
                                         UIFontFeatureSelectorIdentifierKey: @(1)
                                         }];
UIFont *font = [UIFont systemFontOfSize:20];
UIFontDescriptor *originalDescriptor = [font fontDescriptor];
UIFontDescriptor *timeDescriptor = [originalDescriptor fontDescriptorByAddingAttributes: @{UIFontDescriptorFeatureSettingsAttribute:timeFeatureSettings }];
UIFont *timeFont = [UIFont fontWithDescriptor: timeDescriptor
                                         size: 0.0];

引入外部字体

  1. 字体文件后缀是ttf,ttc,otf,otc
  2. 在app bundle中添加
    a.将字体文件放入项目中;
    b.修改plist文件,添加Fonts provided by application 配置,在其中添加item体文件名带后缀;
    c.可以在图形化界面看到新的字体选择,或者像前面那样获取所有字体名称,查看是不是有新添加的
  3. 手动添加
    CTFontManagerRegisterFontsForURL()
    CTFontManagerRegisterFontsForURLs()
    CTFontManagerRegisterGraphicsFont()
    CTFontManagerCreateFontDescriptorsFromURL()
    CTFontManagerCreateFontDescriptorFromData()

图文混排

利用textContainer的exclusion paths可以做到像word中文字环绕在图片周围;

-(UIBezierPath *)translatedBezierPath
{
    CGRect butterflyImageRect = [textView convertRect:imageView.frame fromView:self.view];
    UIBezierPath *newButterflyPath = [UIBezierPath bezierPathWithRect:butterflyImageRect];
    return newButterflyPath;
}
textView = [[UITextView alloc]initWithFrame:CGRectMake(20, 40, [UIScreen mainScreen].bounds.size.width - 40, [UIScreen mainScreen].bounds.size.height - 40)];
textView.font = [UIFont systemFontOfSize:18];
textView.text = @"在排版中,图文混排是非常常见的需求,但有时候我们的图片并一定都是正常的矩形,这个时候我们如果需要将文本环绕在图片周围,就可以用路径排除了。Explosion pats基本原理是将需要被文本留出来的形状的路径告诉文本控件的NSTextContainer对象,NSTextContainer在文字排版时就会避开该路径。";//设置它显示的内容
    
  imageView = [[UIImageView alloc ] init];
  imageView.frame = CGRectMake(80, 80, 100, 100);
  imageView.backgroundColor = [UIColor redColor];
  UIImage *image = [UIImage imageNamed:@"0.jpeg"];
  imageView.image = image;
    
  [self.view addSubview:textView];
  [self.view addSubview:imageView];
    
  textView.textContainer.exclusionPaths = @[[self translatedBezierPath]];

运行之后,就会得到如下效果


ios TextKit中font相关_第5张图片
文字环绕图片

参考资料

Using Text Kit to Draw and Manage Text
Using Fonts with Text Kit
Using Fonts with Text Kit PPT讲解
Text Kit入门
浅析Text Kit
了解ios字体相关知识
ios字体预览
Core Text Font Manager Reference

你可能感兴趣的:(ios TextKit中font相关)