iOS富文本(二)初识Text Kit

概述

Text Kit 是建立在Core Text上的文本布局系统,虽然没有Core Text那么强大的文本处理功能,但是对于大多数常见的文本布局用Text Kit能够很简单的实现,而不是用Core Text底层的 API去实现。在Text Kit出现以前,UITextView一直是基于WebKit构建的,而iOS7以及以后的版本UITextView都基于Text Kit来构建。下图是摘取苹果官方文档展示了Text KitiOS文本与绘图框架中的位置,可见UILabelUITextFieldUITextView都基于Text Kit构建,而Text KitWebKit是基于Core Text构建的。

本篇将介绍Text Kit的一些基本结构与用法。


Text Kit的组件

  • NSTextStorage
    保存管理要显示的文本,NSTextStorageNSAttributeString属性化字符串的子 类。所以NSTextStorage不仅保存文本的内容还有文本的属性信息。
  • NSLayoutManager
    布局管理器,用来管理文本容器的布局
  • NSTextContainer
    表示文本显示的区域,这个区域通常是矩形的,但通过创建NSTextContainer的子类可以描述文本显示的区域为圆形,五边形或其他不规则的形状等。

每一个NSTextStorage对象有多个 NSLayoutManager对象,每个NSLayoutManager有多个NSTextContainer对象,所以对于指定的文本可以同时有多个布局,每种布局又可以有多个显示的区域。

下图摘自苹果官方文档显示了Text Kit中数据在每个组件中的流向

NSTextStorage对象存储的文本信息在NSTextContainer定义的区域范围内由 Text views对象来展示,由NSLayoutManager对象控制布局。


Text Kit 组件使用

每一个UITextView对象都有一个NSTextStorage对象,对应一个NSLayoutManager对象与一个NSLayoutManager对象。每当UITextView对象中的文字发生变化时,NSLayoutManager都会监听到并且根据NSTextContainer提供的绘制区域进行绘制,当布局完成,文本的当前显示状态被设为无效,然后文本管理器将排版好的文本设给文本视图。
下面通过一个简单的代码来描述UITextView这三个组件是如何工作的。
通过Stroyboard创建一个UITextView对象与一个UIView对象

创建UIView对象的类,下面的TextKitView类就是上图中青色的视图

@interface TextKitView ()
@property (weak,nonatomic) IBOutlet UITextView * textView;
@end
@implementation TextKitView

-(void)awakeFromNib
{
    self.textView.layoutManager.delegate = self;  
    //设置NSLayoutManager的代理每当textView内容变化时都会重新布局并且在布局结束后出发代理方法
}
- (void)layoutManagerDidInvalidateLayout:(NSLayoutManager *)sender
{
    [self setNeedsDisplay];
    //每次textView内容变化时对TextKitView进行重绘
}
-(void)drawRect:(CGRect)rect
{
    NSRange range = [self.textView.layoutManager glyphRangeForTextContainer:self.textView.textContainer];
    //得到绘制的范围
    [self.textView.layoutManager drawGlyphsForGlyphRange:range atPoint:CGPointMake(10, 10)];
    //开始绘制
}
-(void)layoutSubviews
{
    self.textContainer.size = self.frame.size;
    // 设置绘制区域
}
@end

实现效果

每当textView中的文字发生变化时青色视图中的文字也会同步改变

多容器布局

由于每个NSTextStorage对象对应多个NSLayoutManager对象,所以单独创建一个NSLayoutManager对象来管理在上面代码中青色视图中的文字显示。

@interface TextKitView ()<NSLayoutManagerDelegate>
@property (weak,nonatomic) IBOutlet UITextView * textView;
@property (nonatomic,strong) NSTextContainer *textContainer;
@property (nonatomic,strong) NSLayoutManager *layoutManager;
@end
@implementation TextKitView

-(void)awakeFromNib
{
    self.textContainer = [[NSTextContainer alloc] init];
    self.layoutManager = [[NSLayoutManager alloc] init];
    self.layoutManager.delegate = self;
    [self.layoutManager addTextContainer:self.textContainer];
    [self.textView.textStorage addLayoutManager:self.layoutManager];
}
- (void)layoutManagerDidInvalidateLayout:(NSLayoutManager *)sender
{
    [self setNeedsDisplay];
}
-(void)drawRect:(CGRect)rect
{
    NSLayoutManager *layoutManager = self.layoutManager;
    NSRange range = [layoutManager glyphRangeForTextContainer:self.textContainer];;
    [layoutManager drawGlyphsForGlyphRange:range atPoint:CGPointMake(10, 10)];
}
-(void)layoutSubviews
{
    self.textContainer.size = self.frame.size;
}

@end

上面代码实现的效果与前一个例子相同,不同的是重新创建了一个NSLayoutManager对象添加到textViewNSTextStorage对象中,新创建一个NSTextContainer对象添加到NSLayoutManager对象中。所以显示的内容是一样的但是拥有不同的容器布局。
代码示例在github 多容器布局 Tag下载


路径排除

Text Kit可以实现在文本布局中排除一些区域让这些区域不显示文字,这对于一些图文混排的效果能够很轻松的实现。Text Kit路径排除主要是用贝塞尔曲线来排除制定区域的文字,下面通过一段简单的代码来实现路径排除效果

@interface ViewController ()
@property (weak, nonatomic) IBOutlet UITextView *textView;

@end
@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    UIBezierPath *path1 = [UIBezierPath bezierPath];
    [path1 addArcWithCenter:CGPointMake(50 ,50)
                    radius:20
                startAngle:0
                  endAngle:M_PI*2
                 clockwise:NO];   //(50,50)为圆心20为半径的圆
    [path1 closePath];

    UIBezierPath *path2 = [UIBezierPath bezierPath];
    [path2 addArcWithCenter:CGPointMake(100 ,100)
                     radius:20
                 startAngle:0
                   endAngle:M_PI*2
                  clockwise:NO];  //(100,100)为圆心20为半径的圆
    [path2 closePath];
    self.textView.textContainer.exclusionPaths = @[path1,path2]; //设置要排除的路径
    // Do any additional setup after loading the view, typically from a nib.
}
@end

实现效果

代码示例可以在github 路径排除 Tag下载


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: iOS 富文本可以通过使用 NSAttributedString 和 NSTextAttachment 类加载 GIF 图片,达到将富文本与动态效果结合的效果。 首先,需要将 GIF 图片转换为 NSData 格式,可通过使用 NSData 的类方法 dataWithContentsOfFile 或者 dataWithContentsOfURL 来实现。 接着,创建 NSTextAttachment 实例,并以 NSData 格式将 GIF 图片作为参数传入。然后,创建 NSMutableAttributedString 实例,并将富文本内容包含在其中。 最后,使用 UILabel、UITextView 或者 UIWebView 等组件来展示富文本内容,并加以控制动态效果的播放周期及重复次数等属性,达到更丰富的用户体验。 需要注意的是,在使用富文本加载 GIF 图片时,应考虑对应用性能及网络耗费等问题进行优化调整,使得应用流畅稳定,并能够节省用户移动数据流量等资源。 ### 回答2: iOS开发中,要加载gif动图作为富文本,可以使用如下的步骤: 1. 引入SDWebImage库:在项目中添加SDWebImage库,这是一个常用的图片加载库,可以方便地加载并显示网络上的图片。 2. 下载gif图片:从网络上找到合适的gif图片,并将其下载到本地。 3. 将gif图片添加到富文本中:使用SDWebImage提供的方法将gif图片添加到富文本中,可以使用`UIImage sd_animatedGIFWithData:`方法将本地的gif图片转换为UIImage对象,并使用该UIImage对象创建一个`NSTextAttachment`对象。 4. 将NSTextAttachment对象添加到NSAttributedString中:将创建好的NSTextAttachment对象添加到NSMutableAttributedString对象中,可以使用`appendAttributedString:`方法将其追加到NSMutableAttributedString对象的末尾。 5. 将NSAttributedString对象显示在界面上:通过UILabel、UITextView等界面控件,将NSMutableAttributedString对象显示在界面上,即可完成富文本加载gif的功能。 需要注意的是,为了保证gif动图的流畅播放,SDWebImage库会将gif图片展示为一系列的静态图片,然后再按照正确的帧率进行播放。另外,对于高性能的gif加载,也可以使用其他优化库,如FLAnimatedImage等。 综上所述,通过引入SDWebImage库、下载gif图片、将图片添加到富文本中,并将富文本显示在界面上等一系列步骤,即可实现在iOS中加载gif动图作为富文本显示的功能。 ### 回答3: 在iOS中,要加载GIF图像并将其显示在富文本中,我们可以采取以下步骤: 1. 首先,我们需要获取GIF图像文件的URL或路径。可以从互联网上下载或从应用程序的资源文件中获取。例如,如果GIF图像保存在应用程序的资源文件中,则可以使用`Bundle.main.url(forResource: "myGif", withExtension: "gif")`方法获取该文件的URL。 2. 接下来,我们需要将GIF图像文件加载到`Data`对象中,以便将其与`NSAttributedString`富文本一起使用。我们可以使用`Data(contentsOf: gifURL)`方法将URL转换为Data对象。 3. 然后,我们可以创建一个`NSTextAttachment`对象,并将GIF图像数据设置为其`image`属性。例如,可以使用`NSTextAttachment(image: UIImage(data: gifData)!)`来创建`NSTextAttachment`对象。 4. 然后,我们可以使用`NSAttributedString`的`append`方法将`NSTextAttachment`对象添加到富文本中,并设置其适当的位置。例如,可以使用`attributedString.append(NSAttributedString(attachment: textAttachment))`语句将`NSTextAttachment`对象添加到`attributedString`富文本字符串中。 5. 最后,我们可以将包含GIF图像的富文本字符串应用于文本视图或标签等UI元素,以便在界面上显示GIF图像。例如,对于UILabel,可以使用`label.attributedText = attributedString`将富文本字符串应用于标签。 综上所述,以上是利用iOS富文本加载GIF的简要步骤。通过将GIF图像文件加载到`Data`对象中,然后将其作为`NSTextAttachment`对象添加到富文本字符串中,我们可以在富文本中显示GIF图像,并将其应用于iOS界面中的相应UI元素。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值