|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
管理你的ViewController的层次可以自己写View切换的动画关掉他默认的动画文档:还有个蛋疼的UIWindow都快忘了他了因为iOS是从MacosX过来的很多工具直接拿来用这个UIWindow就是在iOS里每个App独占屏幕所以同时存在的只有一个UIWindowiOS7的公布给开辟者的案头带来了良多新工具。个中一个就是TextKit(文本工具箱)。TextKit由很多新的UIKit类构成,望文生义,这些类就是用来处置文本的。在这里,我们将先容TextKit的出处、它的构成,和经由过程几个例子注释开辟者如何将它派上年夜用处。
可是起首我们得有一点背景常识:TextKit多是近期对UIKit最主要的增补了。iOS7的新界面用纯文本按钮交换了大批的图标和边框。总的来讲,文本和文本结构在新的操纵体系的表面方面比之前主要多了。iOS7的从头计划完整是被文本驱动,如许说大概其实不夸大——而文本全体是TextKit来处置的。
告知你这个变化究竟有多年夜吧:iOS7之前的一切版本,(几近)一切的文本都是WebKit来处置的。对:WebKit,web扫瞄器引擎。一切UILabel、UITextField,和UITextView都在背景以某种体例利用web视图来举行文本结构和衬着。为了新的界面作风,它们全都被从头计划以利用TextKit。
iOS上文本的冗长汗青
这些新类并非用来交换开辟者之前利用的类。对SDK来讲,TextKit供应的是全新的功效。iOS7之前,TextKit供应的功效必需都手动完成。这是现有功效之间缺掉的环节。
临时以来,只要一个基础的文本结构和衬着框架:CoreText。也有一个路子读取用户的键盘输出:UITextInput协定。iOS6乃至有一个路子来复杂地猎取体系的文本选择:承继UITextView。
(这多是重点,我应当公然我开辟文本编纂器的十年履历了)在衬着文本和读取键盘输出之间存在着伟大(跟我读:伟大)的缺口。这个缺口大概也是招致很少有富文本大概语法高亮编纂器的缘故原由了——毫无疑问,开辟一个好用的文本编纂器得泯灭几个月的工夫。
就如许——以下是iOS文本(不那末)冗长汗青的冗长提要:
iOS2:这是第一个公然的SDK,包含一个复杂的文本显现组件(UILabel),一个复杂的文本输出组件(UITextField),和一个复杂的、可转动、可编纂的而且撑持更大批文本的组件:UITextView。这些组件都只撑持纯文本,没有文本选择撑持(仅撑持拔出点),除设置字体和文本色彩外几近没有其他可定制功效。
iOS3:新特征有复制和粘贴,和复制粘贴所必要的文本选择功效。数据探测器(DataDetector)为文本视图供应了一个高亮德律风号码和链接的办法。但是,除翻开或封闭这些特征外,开辟者基础上没有甚么其余事变能够做。
iOS3.2:iPad的呈现带来了CoreText,也就是后面提到的初级文本结构和衬着引擎(从MacOSX10.5移植过去的),和UITextInput,后面也提到的键盘存取协定。Apple将Pages作为挪动设备上文本编纂功效的榜样工程(附注1)。但是,因为我后面提到的框架缺口,只要很少的使用利用它们。
iOS4:iOS3.2公布仅仅几个月后就公布了,文本方面没有一丁点新功效。(团体履历:在WWDC,我走近工程师们,告知他们我想要一个完美的iOS文本结构体系。回覆是:“哦…提交个哀求。”不出所料…)
iOS5:文本方面没啥变更。(团体履历:在WWDC,我和工程师们谈及iOS上文本体系。回覆是:“我们没有看到太多的哀求…”靠!)
iOS6:有些举措了:属性文本编纂被到场了UITextView。很不幸的是,它很难定制。默许的UI有粗体、斜体和下划线。用户能够设置字体巨细和色彩。粗看起来相称不错,但仍是没法把持结构大概供应一个便当的路子来定制文本属性。但是关于(文本编纂)开辟者,有一个年夜的新功效:能够承继UITextView了,如许的话,除之前版本供应的键盘输出外,开辟者能够“收费”取得文本选择功效。必需完成一个完整自界说的文本选择功效,多是良多对非纯文本工具开辟的实验前功尽弃的缘故原由。(团体履历:我,WWDC,工程师们。我想要一个iOS的文本体系。回覆:“嗯。吖。是的。大概?看,它只是不实行…”以是究竟仍是有但愿,对吧?)
iOS7:终究来了,TextKit。
功效
以是我们到了。iOS7带着TextKit上岸了。我们看看它能够做甚么!深切之前,我还想提一下,严厉来讲,这些事变中的年夜部分之前都能够做。假如你有大批的资本和工夫来用CoreText构建一个文本引擎,这些都是能够做的。可是假如之前你想构建一个完美的富文本编纂器,你得消费几个月的工夫。如今就十分复杂,你只必要到在Xcode里翻开一个界面文件,然后将UITextView拖到你的试图把持器,就能够取得一切的功效:
字距调剂(Kerning):一切的字符都有复杂的二次的外形,这些外形必需被准确地安排,相互相邻的,别如许想了。比方,古代文本结构会思索到一个年夜写的“T”的“两翼”上面有一些空缺,以是它会把前面的小写字母向左移让它们更接近点。从而年夜年夜进步了文本的易读性,出格是在更长的笔墨中:
<br>
连写:我以为这次要是个艺术功效,但当某些字符组合(如“f”前面是“l”)利用组合标记(所谓的字形(glyph))绘制时,有些文本的确看起来更好(更美妙)。
<br>
图象附件:如今能够在文本视图内里增加图象了。
断字:编纂文本时没那末主要,但假如要以悦目易读的体例展示文本时,这就相称主要。断字意味着外行界限处罚割单词,从而为全体文本创立一个更划一的排版和表面。团体履历:iOS7之前,开辟者必需间接利用CoreText。像如许:起首以句子为基本检测文本言语,然后猎取句子中每一个单词大概的断字点,然后在每个大概的断字点上拔出定制的连字占位字符。筹办好以后,运转CoreText的结构办法并手动将连字符拔出到断行。假如你想失掉好的效果,以后你得反省带有连字符的文本没有超越行界限,假如超越了,在运转一次行的结构办法,这一次不要利用前次利用的断字点。利用TextKit的话,就十分复杂了,设置hyphenationFactor属性就能够启用断字。
可定制性:对我来讲,乃至比改善过的排版还多,这是个新的功效。之前开辟者必需在利用现有的功效和本人全体重头写之间做出选择。如今供应了一整套类,它们有代办署理协定,大概能够被掩盖从而改动部分举动。比方,不用重写全部文本组件,你如今就能够改动指订单词的断行举动。我以为这是个成功。
更多的富文本属性:如今能够设置分歧的下划线款式(双线、粗线、虚线、点线,大概它们的组合)。进步文本的基线十分简单,这可用来设置上标数字。开辟者也不再必要本人为定制衬着的文本绘制背景色彩了(CoreText不撑持这些功效)。
序列化:已往没有内置的办法从磁盘读取带文本属性的字符串。大概再写回磁盘。如今有了。
文本款式:iOS7的界面引进了一个全局预界说的文本范例的新观点。这些文本范例分派了一个全局预界说的表面。幻想情形下,这可让全部体系的题目和一连文本具有分歧的作风。经由过程设置使用,用户能够界说他们的浏览习气(比方文本巨细),那些利用文本款式的使用将主动具有准确的文本巨细和表面。
文本效果:最初也是最不主要的。iOS7有且唯一一个文本效果:凸版。利用此效果的文本看起来像是盖在纸下面一样。内暗影,等等。团体概念:真的?靠…?在一个已完整完全不成宽恕地枪毙了一切无用的复古粉饰的操纵体系上,谁会必要这个像文本盖在纸上的表面?
布局
大概概览一个体系最好的办法是画一幅图。这是UIKit文本体系——TextKit的简图,:
<br>
从上图能够看出来,要让一个文本引擎事情,必要几个介入者。我们将从外到里先容它们:
字符串(String):要绘制文本,那末一定在某个中央有个字符串存储它。在默许的布局中,NSTextStorage保留并办理这个字符串,在这类情形中,它能够阔别绘制。但其实不必定非得如许。利用TextKit时,文本能够来自任何合适的来历。比方,关于一个代码编纂器,字符串能够是一棵包括一切显现的代码的布局信息的正文语法树(annotatedsyntaxtree,AST)。利用一个定制的文本存储,这个文本只在前面静态地增加字体或色彩高亮等文本属性粉饰。这是第一次,开辟者能够间接为文本组件利用本人的模子。只必要一个出格计划的文本存储。即:
NSTextStorage:假如你把文本体系看作一个模子-视图-把持器(MVC)架构,这个类代表的是模子。文本存储是中央对象,它晓得一切的文本和属性信息。它只供应了两个存取器办法存取它们,并供应了别的两个办法来修正它们。前面我们将进一步懂得它们。如今主要的是你得了解NSTextStorage是从它的父类NSAttributedString承继了这些办法。这就很分明了,文本存储——从文本体系看来——仅仅是一个带有属性的字符串,和几个扩大。这二者独一的严重分歧点是文本存储包括了一个办法来发送内容改动的关照。我们会即刻先容这部份内容。
UITextView:仓库的另外一头是实践的视图。在TextKit中,文本视图有两个目标:第一,它是文本体系用来绘制的视图。文本视图它本人其实不会做任何绘制;它仅仅供应一个供别的类绘制的地区。作为视图层级机构中独一的组件,第二个目标是处置一切的用户交互。详细来讲,文本视图完成UITextInput的协定来处置键盘事务,它为用户供应了一种路子来设置一个拔出点或选择文本。它其实不对文本做任何实践上的改动,仅仅将这些改动哀求转发给方才会商的文本存储。
NSTextContainer:每一个文本视图界说了一个文本能够绘制的地区。为此,每一个文本视图都有一个文本容器,它准确地形貌了这个可用的地区。在复杂的情形下,这是一个垂直的无穷相称年夜的矩形地区。文本被添补到这个地区,而且文本视图同意用户转动它。但是,在更初级的情形下,这个地区多是一个无穷年夜的矩形。比方,当衬着一本书时,每页都有最年夜的高度和宽度。文本容器会界说这个巨细,而且不承受任何超越的文本。不异情形下,一幅图象大概占有了页面的一部分,文本应当沿着它的边沿从头排版。这也是由文本容器来处置的,我们会在前面的例子中看到这一点。
NSLayoutManager:结构办理器是中央组件,它把一切组件粘合在一同:
- 1、这个办理器监听文本存储中文本或属性改动的关照,一旦吸收到关照就触公布局历程。
- 2、从文本存储供应的文本入手下手,它将一切的字符翻译为字形(Glyph)(附注2).
- 3、一旦字形全体天生,这个办理器向它的文本容器(们)查询文本可用以绘制的地区
- 4、然后这些地区被行慢慢添补,而行又被字形慢慢添补。一旦一行添补终了,下一行入手下手添补。
- 5、关于每行,结构办理器必需思索断行举动(放不下的单词必需移到下一行)、连字符、内联的图象附件等等。
- 6、当结构完成,文本确当前显现形态被设为有效,然后文本办理器将后面几步排版好的文本设给文本视图。
CoreText:没有间接包括在TextKit中,CoreText是举行实践排版的库。关于结构办理器的每步,CoreText被如许或那样的体例挪用。它供应了从字符到字形的翻译,用它们来添补行,和倡议断字点。
Cocoa文本体系
创立像TextKit如许复杂庞大的体系一定不是件复杂疾速的事变,并且一定必要丰厚的履历和常识。在iOS的后面6个主版本中,一向没有供应一个“真实的”文本组件,这也申明了这一点。Apple把它视为一个年夜的新特征,固然没啥成绩。可是它真的是全新的吗?
这里有个数字:在UIKit的131个大众类中,只要9个的名字没有利用UI作为前缀。这9个类利用的是旧体系的的、旧天下的(跟我读:MacOS)前缀NS。并且这九个类内里,有七个是用来处置文本的。偶合?好吧…
这是Cocoa文本体系的简图。无妨和下面TextKit的那幅图作一下对照。
<br>
惊人地类似。很分明,最最少次要部分,二者是不异的。很分明——除右侧部分和NSTextView和UITextView——次要的类全体不异。TextKit是(最少部分是)从Cocoa文本体系移植到iOS。(我之前一向哀求的谁人,耶!)
进一步对照仍是能看出一些分歧的。最值得注重的有:
在iOS上没有NSTypesetter和NSGlyphGenerator这两个类。在MacOS上有良多办法来定制排版,这被极年夜地简化了。这能够往失落一些笼统观点,并将这个历程兼并到NSLayoutManager中来。保存上去的是多数的代办署理办法,以用来变动文本结构和断行举动。
这些类的iOS完成供应了几个新的并且十分便当的功效。在Cocoa中,必需手工地将断定的地区从文本容器分别出来(见上)。而UIKit类供应了一个复杂的exclusionPaths属性就能够做到这一点。
有些功效未能供应,好比,内嵌表格,和对非图象的附件的撑持。
只管有这些区分,总的来讲体系仍是一样的。NSTextStorage在两个体系是是千篇一律的,NSLayoutManager和NSTextContainer也没有太年夜的分歧。这些变化,在没有太多往除对一些惯例的撑持的情形下,看来(某些情形下年夜年夜地)使文本体系的利用变得更加简单。我以为这是件功德。
过后回忆我从Apple工程师那边失掉的关于将Cocoa文本体系移植到iOS的谜底,我们能够失掉一些背景信息。拖到如今并减少功效的缘故原由很复杂:功能、功能、功能。文本结构多是极端高贵的义务——内存方面、电量方面和工夫方面——出格是在挪动设备上。Apple必需接纳更复杂的办理计划,并比及处置才能可以最少部分撑持一个完美的文本结构引擎。
示例
为了申明TextKit的才能,我创立了一个小的演示项目,你能够在GitHub上找到它。在这个演示程序中,我只完成了一些之前不简单完成的功效。我必需供认编码事情只花了我星期天的一个上午的工夫;假如之前要做一样的事变,我得花几天乃至几个礼拜。
TextKit包含了凌驾100个办法,一篇文章基本没举措尽数触及。而现实上,年夜多半时分,你必要的仅仅是一个准确的办法,TextKit的利用和定制性也仍有待探究。以是我决意做四个更小的演示程序,而非一个年夜的演示程序来展现一切功效。每一个演示程序中,我试着演示针对分歧的方面和分歧的类举行定制。
演示程序1:设置
让我们从最复杂的入手下手:设置文本体系。正如你在下面TextKit简图中看到的,NSTextStorage、NSLayoutManager和NSTextContainer之间的箭头都是有两个头的。我试图形貌它们的干系是1对N的干系。就是那样:一个文本存储能够具有多个结构办理器,一个结构办理器也能够具有多个文本容器。这些多重性带来了很好的特征:
- 将多个文本办理器附加到一个文本存储上,能够发生不异文本的多种视觉体现,并且它们能够并排显现。每个体现能够自力地安排和修正巨细。假如响应的文本视图可编纂,那末在某个视图上做的一切修正城市即刻反应到一切视图上。
- 将多个文本容器附加到一个文本办理器上,能够将一个文天职布到多个视图展示出来。比方很有效的基于页面的结构:每一个页面包括一个独自的视图。一个文本办理器使用这些视图的文本容器,将文天职布到这些视图上。
在storyboard大概interface文件中实例化UITextView时,它会预设置一个文本体系:一个文本存储,援用一个文本办理器,尔后者又援用一个文本容器。一样地,一个文本体系栈也能够经由过程代码间接创立:
1
2
3
4
5
6
7
8
9
10
NSTextStorage*textStorage=[NSTextStoragenew];
NSLayoutManager*layoutManager=[NSLayoutManagernew];
[textStorageaddLayoutManager:layoutManager];
NSTextContainer*textContainer=[NSTextContainernew];
[layoutManageraddTextContainer:textContainer];
UITextView*textView=[[UITextViewalloc]initWithFrame:someFrame
textContainer:textContainer];
这是最复杂的体例。手工创立一个文本体系,独一必要记着的事变是你的视图把持器必需retain文本存储。在栈底的文本视图只保存了对文本存储和结构办理器的弱援用。当文本存储被开释时,结构办理器也被开释了,如许留给文本视图的就只要一个断开的容器了。
这个划定规矩有一个破例。只要从一个interface文件或storyboard实例化一个文本视图时,文本视图的确会retain文本存储。框架利用了一些黑邪术以确保一切的对象都被retain,而无需创建一个retain环。
记着这些以后,创立一个更初级的设置也十分复杂。假定在一个视图内里仍旧有一个从nib实例化的文本视图,叫做originalTextView。增添对不异文本的第二个文本视图只必要复制下面的代码,偏重用originalTextView的文本存储:
1
2
3
4
5
6
7
8
9
10
NSTextStorage*sharedTextStorage=originalTextView.textStorage;
NSLayoutManager*otherLayoutManager=[NSLayoutManagernew];
[sharedTextStorageaddLayoutManager:otherLayoutManager];
NSTextContainer*otherTextContainer=[NSTextContainernew];
[otherLayoutManageraddTextContainer:otherTextContainer];
UITextView*otherTextView=[[UITextViewalloc]initWithFrame:someFrame
textContainer:otherTextContainer];
将第二个文本容器附加到结构办理器也差未几。例如说我们但愿下面例子中的文本添补两个文本视图,而非一个。复杂:
1
2
3
4
5
NSTextContainer*thirdTextContainer=[NSTextContainernew];
[otherLayoutManageraddTextContainer:thirdTextContainer];
UITextView*thirdTextView=[[UITextViewalloc]initWithFrame:someFrame
textContainer:thirdTextContainer];
但有一点必要注重:因为在otherTextView中的文本容器能够无穷地调剂巨细,thirdTextView永久不会失掉任何文本。因而,我们必需指定文本应当从一个视图回流到别的视图,而不该该调剂巨细大概转动:
1
otherTextView.scrollEnabled=NO;
不幸的是,看来将多个文本容器附加到一个文本办理器会禁用编纂功效。假如必需保存编纂功效的话,你只能够将一个文本容器附加到一个文本办理器上。
想要一个这个设置的可运转的例子的话,请在后面提到的TextKitDemo中检察“Configuration”标签页。
演示程序2:语法高亮
假如设置文本视图不是那末使人冲动,那末这里有更风趣的:语法高亮!
看看TextKit组件的义务分别,就很分明语法高亮应当在文本存储上完成。由于NSTextStorage是一个类簇(附注3),创立它的子类必要做很多事情。我的设法是创建一个复合对象:完成一切的办法,但只是将对它们的挪用转发给一个实践的实例,将输出输入参数大概了局修正为但愿的模样。
NSTextStorage承继自NSMutableAttributedString,而且必需完成以下四个办法——两个getter和两个setter:
<p>1
2
3
4
5
-(NSString*)string;
-(NSDictionary*)attributesAtIndex:(NSUInteger)location
effectiveRange:(NSRangePointer)range;
-(void)replaceCharactersInRange:(NSRange)rangewithString:(NSString*)str;
<p>-(void |
|