iOS文本布局探讨之一——文本布局框架TextKit浅析(一)

简介: iOS文本布局探讨之一——文本布局框架TextKit浅析

一、引言


       在iOS开发中,处理文本的视图控件主要有4中,UILabel,UITextField,UITextView和UIWebView。其中UILabel与UITextField相对简单,UITextView是功能完备的文本布局展示类,通过它可以进行复杂的富文本布局,UIWebView主要用来加载网页或者pdf文件,其可以进行HTML,CSS和JS等文件的解析。


       TextKit是一个偏上层的开发框架,在iOS7以上可用,使用它开发者可以方便灵活处理复杂的文本布局,满足开发中对文本布局的各种复杂需求。TextKit实际上是基于CoreText的一个上层框架,其是面向对象的,如果TextKit中提供的API无法满足需求,可以使用CoreText中的API进行更底层的开发。


       官方文档中的一张图片很确切,经常会被用来描述TextKit框架在iOS系统文本渲染中所处的位置。

image.png



二、TextKit框架的结构


       界面在进行文本的渲染时,有下面几个必要条件:


1.要渲染展示的内容。


2.将内容渲染在某个视图上。


3.内容渲染在视图上的尺寸位置和形状。


在TextKit框架中,提供了几个类分别对应处理上述的必要条件:


1.NSTextStorage对应要渲染展示的内容。


2.UITextView对应要渲染的视图。


3.NSTextContainer对应渲染的尺寸位置和形状信息。


除了上述3个类之外,TextKit框架中的NSLayoutManager类作为协调者来进行布局操作。


上述关系如下图所示:


image.png


三、使用TextKit进行文本布局流程


       个人理解,TextKit主要用于更精细的处理文本布局以及进行复杂的图文混排布局,使用TextKit进行文本的布局展示十分繁琐,首先需要将显示内容定义为一个NSTextStorage对象,之后为其添加一个布局管理器对象NSLayoutManager,在NSLayoutManager中,需要进行NSTextContainer的定义,定义多了NSTextContainer对象则会将文本进行分页。最后,将要展示的NSTextContainer绑定到具体的UITextView视图上。


示例代码如下:


   //定义Container

   NSTextContainer * container = [[NSTextContainer alloc]initWithSize:CGSizeMake(150, 200)];

   //定义布局管理类

   NSLayoutManager * layoutManager = [[NSLayoutManager  alloc]init];

   //将container添加进布局管理类管理

   [layoutManager addTextContainer:container];

   //定义一个Storage

   NSTextStorage * storage = [[NSTextStorage alloc]initWithString:@"The NSTextContainer class defines a region where text is laid out. An NSLayoutManager uses NSTextContainer to determine where to break lines, lay out portions of text, and so on."];

   //为Storage添加一个布局管理器

   [storage addLayoutManager:layoutManager];

   //将要显示的container与视图TextView绑定

   UITextView * textView = [[UITextView alloc]initWithFrame:self.view.frame textContainer:container];

   [self.view addSubview:textView];

上面代码演示的过程如下图所示:


image.png


需要注意,TextKit进行布局的核心思路是最终的视图对应一个文本块Container,并不是一段文本内容Storage,LayoutManager会将完整的内容根据其中Container的尺寸进行分页,TextView根据需要显示的部分进行Container的选择。


四、了解NSTextContainer类


       NSTextContainer可以简单理解为创建一个文本区块,文本内容将在这个区块中进行渲染,其中常用属性与方法如下:


//初始化方法 设置区块的尺寸

- (instancetype)initWithSize:(CGSize)size;

//与其绑定的layoutManager 需要注意,不是设置这个属性 使用[NSLayoutManager addTextContainer:]方式来进行绑定

@property(nullable, assign, NS_NONATOMIC_IOSONLY) NSLayoutManager *layoutManager;

//替换绑定的布局管理类对象

- (void)replaceLayoutManager:(NSLayoutManager *)newLayoutManager;

//获取区块尺寸

@property(NS_NONATOMIC_IOSONLY) CGSize size;

//设置从区块中剔除某一区域

@property(copy, NS_NONATOMIC_IOSONLY) NSArray<UIBezierPath *> *exclusionPaths;

//设置截断模式 需要注意 这个属性的设置只是会影响此区块的最后一行的截断模式

@property(NS_NONATOMIC_IOSONLY) NSLineBreakMode lineBreakMode;

//设置每行文本左右空出的间距

@property(NS_NONATOMIC_IOSONLY) CGFloat lineFragmentPadding;

//设置TextView上可输入的文本最大行数

@property(NS_NONATOMIC_IOSONLY) NSUInteger maximumNumberOfLines;


//这个方法用于提供给子类进行重写 这里返回的Rect是可以布局文本的区域

- (CGRect)lineFragmentRectForProposedRect:(CGRect)proposedRect atIndex:(NSUInteger)characterIndex writingDirection:(NSWritingDirection)baseWritingDirection remainingRect:(nullable CGRect *)remainingRect;

//这个BOOL值的属性决定Container的宽度是否自适应TextView的宽度

@property(NS_NONATOMIC_IOSONLY) BOOL widthTracksTextView;

//这个BOOL值的属性决定Container的高度是否自适应TextView的高度

@property(NS_NONATOMIC_IOSONLY) BOOL heightTracksTextView;

上面所列举的方法中,exclusionPaths属性十分强大,通过设置它,可以将布局区域内剔出一块区域不进行布局,示例代码如下:


[super viewDidLoad];

   NSTextContainer * container = [[NSTextContainer alloc]initWithSize:CGSizeMake(300, 500)];


   UIBezierPath * path = [UIBezierPath bezierPathWithArcCenter:self.view.center radius:70 startAngle:0 endAngle:M_PI*2 clockwise:YES];

   container.exclusionPaths = @[path];

   container.lineBreakMode = NSLineBreakByCharWrapping;

   NSLayoutManager * layoutManager = [[NSLayoutManager  alloc]init];

   [layoutManager addTextContainer:container];

   NSTextStorage * storage = [[NSTextStorage alloc]initWithString:@"The NSTextContainer class defines a region where text is laid out. An NSLayoutManager uses NSTextContainer to determine where to break lines, lay out portions of text, and so on. An NSTextContainer object normally defines rectangular regions, but you can define exclusion paths inside the text container to create regions where text does not flow. You can also subclass to create text containers with nonrectangular regions, such as circular regions, regions with holes in them, or regions that flow alongside graphics.The NSTextContainer class defines a region where text is laid out. An NSLayoutManager uses NSTextContainer to determine where to break lines, lay out portions of text, and so on. An NSTextContainer object normally defines rectangular regions, but you can define exclusion paths inside the text container to create regions where text does not flow. You can also subclass to create text containers with nonrectangular regions, such as circular regions, regions with holes in them, or regions that flow alongside graphics.An NSLayoutManager uses NSTextContainer to determine where to break lines, lay out portions of text, and so on. An NSTextContainer object normally defines rectangular regions, but you can define exclusion paths inside the text container to create regions where text does not flow. You can also subclass to create text containers with nonrectangular regions, such as circular regions, regions with holes in them, or regions that flow alongside graphics."];

   [storage addLayoutManager:layoutManager];

   UITextView * textView = [[UITextView alloc]initWithFrame:self.view.frame textContainer:container];

   [self.view addSubview:textView];

效果如下图:

image.png

目录
打赏
0
0
0
0
47
分享
相关文章
iOS应用开发中有多种主流框架
iOS应用开发中有多种主流框架
316 60
深入探索iOS开发中的SwiftUI框架
【10月更文挑战第21天】 本文将带领读者深入了解Apple最新推出的SwiftUI框架,这一革命性的用户界面构建工具为iOS开发者提供了一种声明式、高效且直观的方式来创建复杂的用户界面。通过分析SwiftUI的核心概念、主要特性以及在实际项目中的应用示例,我们将展示如何利用SwiftUI简化UI代码,提高开发效率,并保持应用程序的高性能和响应性。无论你是iOS开发的新手还是有经验的开发者,本文都将为你提供宝贵的见解和实用的指导。
149 66
未来已来:探索区块链、物联网与虚拟现实技术的融合与应用安卓与iOS开发中的跨平台框架选择
【8月更文挑战第30天】在科技的巨轮下,新技术不断涌现,引领着社会进步。本文将聚焦于当前最前沿的技术——区块链、物联网和虚拟现实,探讨它们各自的发展趋势及其在未来可能的应用场景。我们将从这些技术的基本定义出发,逐步深入到它们的相互作用和集成应用,最后展望它们如何共同塑造一个全新的数字生态系统。
探索iOS开发中的SwiftUI框架
【10月更文挑战第39天】在苹果的生态系统中,SwiftUI框架以其声明式语法和易用性成为开发者的新宠。本文将深入SwiftUI的核心概念,通过实际案例展示如何利用这一框架快速构建用户界面,并探讨其对iOS应用开发流程的影响。
基于开源IM即时通讯框架MobileIMSDK:RainbowChat-iOS端v9.1版已发布
RainbowChat是一套基于开源IM聊天框架 MobileIMSDK 的产品级移动端IM系统。RainbowChat源于真实运营的产品,解决了大量的屏幕适配、细节优化、机器兼容问题
99 5
探索iOS开发中的SwiftUI框架
【10月更文挑战第21天】在苹果生态系统中,SwiftUI的引入无疑为iOS应用开发带来了革命性的变化。本文将通过深入浅出的方式,带领读者了解SwiftUI的基本概念、核心优势以及如何在实际项目中运用这一框架。我们将从一个简单的例子开始,逐步深入到更复杂的应用场景,让初学者能够快速上手,同时也为有经验的开发者提供一些深度使用的技巧和策略。
81 1
安卓与iOS的跨平台开发:Flutter框架深度解析
在移动应用开发的海洋中,Flutter作为一艘灵活的帆船,正引领着开发者们驶向跨平台开发的新纪元。本文将揭开Flutter神秘的面纱,从其架构到核心特性,再到实际应用案例,我们将一同探索这个由谷歌打造的开源UI工具包如何让安卓与iOS应用开发变得更加高效而统一。你将看到,借助Flutter,打造精美、高性能的应用不再是难题,而是变成了一场创造性的旅程。
探索iOS应用开发的新趋势:SwiftUI和Combine框架
【8月更文挑战第6天】随着Apple不断推动其操作系统的进化,iOS开发领域也迎来了新的变革。本文将深入探讨SwiftUI和Combine框架如何革新iOS应用开发流程,提升开发者的工作效率,并改善最终用户的体验。我们将从这两个框架的基本概念出发,分析它们的核心优势,并预测它们将如何塑造iOS开发的未来。
探索iOS开发中的SwiftUI框架
【9月更文挑战第21天】在iOS应用开发的广阔天地中,SwiftUI框架如一股清新之风,为开发者带来了声明式语法的便捷与高效。本文将深入探讨SwiftUI的核心概念、布局方式及数据绑定机制,同时通过实例演示如何运用SwiftUI构建用户界面,旨在引领读者领略SwiftUI的魅力,并激发其对iOS开发新趋势的思考与实践。
57 6
探索iOS应用开发中的SwiftUI框架
【9月更文挑战第26天】 在iOS开发的海洋中,SwiftUI犹如一艘现代的快艇,引领着开发者们驶向更加高效与直观的编程体验。本文将带你领略SwiftUI的魅力,从其设计理念到实际应用,我们将一步步揭开它如何简化界面构建过程的面纱。通过对比传统方式,你将看到SwiftUI如何让代码变得像诗一样优美,同时保持强大的功能性和灵活性。准备好让你的iOS开发技能加速升级,一起驾驭这股新潮流吧!

热门文章

最新文章

  • 1
    【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    47
  • 2
    【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    19
  • 3
    【01】噩梦终结flutter配安卓android鸿蒙harmonyOS 以及next调试环境配鸿蒙和ios真机调试环境-flutter项目安卓环境配置-gradle-agp-ndkVersion模拟器运行真机测试环境-本地环境搭建-如何快速搭建android本地运行环境-优雅草卓伊凡-很多人在这步就被难倒了
    59
  • 4
    Cellebrite UFED 4PC 7.71 (Windows) - Android 和 iOS 移动设备取证软件
    32
  • 5
    【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
    13
  • 6
    iOS各个证书生成细节
    16
  • 7
    iOS7应用开发7:自定义视图、手势操作
    1
  • 8
    IOS小工具以及精彩的博客
    507
  • 9
    iOS - Swift NSPoint 位置
    1
  • 10
    iOS开发-UIScrollView原理
    655
  • 1
    iOS各个证书生成细节
    16
  • 2
    【01】噩梦终结flutter配安卓android鸿蒙harmonyOS 以及next调试环境配鸿蒙和ios真机调试环境-flutter项目安卓环境配置-gradle-agp-ndkVersion模拟器运行真机测试环境-本地环境搭建-如何快速搭建android本地运行环境-优雅草卓伊凡-很多人在这步就被难倒了
    59
  • 3
    Cellebrite UFED 4PC 7.71 (Windows) - Android 和 iOS 移动设备取证软件
    32
  • 4
    【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    47
  • 5
    【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    40
  • 6
    【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
    32
  • 7
    uniapp开发ios打包Error code = -5000 Error message: Error: certificate file(p12) import failed!报错问题如何解决
    147
  • 8
    【05】2025年1月首发完整版-篇幅较长-苹果app如何上架到app store完整流程·不借助第三方上架工具的情况下无需花钱但需仔细学习-优雅草央千澈详解关于APP签名以及分发-们最关心的一篇来了-IOS上架app
    279
  • 9
    app开发之安卓Android+苹果ios打包所有权限对应解释列表【长期更新】-以及默认打包自动添加权限列表和简化后的基本打包权限列表以uniapp为例-优雅草央千澈
    99
  • 10
    深入探索iOS开发中的SwiftUI框架
    149
  • AI助理

    你好,我是AI助理

    可以解答问题、推荐解决方案等