iOS之UI高级---如何理解图文混排
2015-11-12 16:19
645 查看
参考资料:
1.http://www.allenchiang.com/2014/05/28/core-text/
2.唐巧:《iOS进阶》
上图展示的iOS7的框架层次结构,可以看到基于Core Text的Text Kit为上述3个常用控件提供了技术支持
Core Text is an advanced, low-level technology for laying out text and handling fonts. Core Text works directly with Core Graphics (CG), also known as Quartz, which is the high-speed graphics rendering engine that handles two-dimensional imaging at the lowest level in OS X and iOS.
下面我们跟着这段解释详细了解一下其中的关键字:
①low-level technology:
它直接和底层的CoreGraphics联系,表明它也是一种底层的技术。从中也可以了解它的实现是通过C语言的
②laying out text and handling fonts:
它是一种处理字符的布局引擎(当然,不仅仅是字符),通过这个布局引擎,我们可以实现图文混排、文字链接等UILabel、UITextField控件无法实现的功能
我们可以这么理解字符如何绘制到屏幕上:
①:首先创建一个属性字符串CFAttributedStringRef,它包括了字符的颜色、大小、字体等信息
②:然后创建CTFramesetter,它包括了字符的行间距、缩进、断行方式等
生成的CTFramesetter同时也会唤起一个CTTypesetter,它的作用是将CFAttributedStringRef中的字符转换成对应的字形
③:由①②我们可以生成一个CTFrame,可以想象成一个字符区域。(我们添加一个视图的时候,要设置视图的frame。同理添加字符的时候,也要设置一个frame)
CTFrame中包含CTLine、CTRun。CTLine即每一行,而CTRun是指一行中连续的一段包含同样属性和方向的文字。CTLine中可以有多个CTRun
1.首先,我们看看一个字形是如何定义的:
我们要注意的有3个:
①Bounding
②Ascent
③Descent
2.那么图文混排中的文字和颜色到底是如何绘制上去的呢?
①如果我们要绘制文字: 通过以下方法直接绘制CTFrame
②如果我们要绘制图片:
其实只是告诉Core Text有一个地方需要占多大的位置,这样系统就会在指定的地方给出了足够的空间。真正的图像绘制其实还是需要我们自己通过Core Graphic来做。
实际操作中,可以:创建空白占位符,并且设置它的CTRunDelegate信息(通过信息判断图片需要的空间大小)
例如:
1.http://www.allenchiang.com/2014/05/28/core-text/
2.唐巧:《iOS进阶》
一、iOS开发中的文字排版
通常我们使用UILabel、UITextField、UITextView在iOS上展示一些我们需要的文字。前者用于简单的展示,后两者可以用于接受用户的输入。通常情况下我们用上述3者展示简单的纯文本,如果我们需要展示图文混排或者稍微带一点排版样式的文字时,我们需要使用更底层的一些技术,比如Text Kit 或者 Core Text。上图展示的iOS7的框架层次结构,可以看到基于Core Text的Text Kit为上述3个常用控件提供了技术支持
二、iOS中的CoreText介绍
苹果官方文档的解释:Core Text is an advanced, low-level technology for laying out text and handling fonts. Core Text works directly with Core Graphics (CG), also known as Quartz, which is the high-speed graphics rendering engine that handles two-dimensional imaging at the lowest level in OS X and iOS.
下面我们跟着这段解释详细了解一下其中的关键字:
①low-level technology:
它直接和底层的CoreGraphics联系,表明它也是一种底层的技术。从中也可以了解它的实现是通过C语言的
②laying out text and handling fonts:
它是一种处理字符的布局引擎(当然,不仅仅是字符),通过这个布局引擎,我们可以实现图文混排、文字链接等UILabel、UITextField控件无法实现的功能
三、CoreText布局引擎结构
首先看一幅图(官方文档中的图):我们可以这么理解字符如何绘制到屏幕上:
①:首先创建一个属性字符串CFAttributedStringRef,它包括了字符的颜色、大小、字体等信息
②:然后创建CTFramesetter,它包括了字符的行间距、缩进、断行方式等
生成的CTFramesetter同时也会唤起一个CTTypesetter,它的作用是将CFAttributedStringRef中的字符转换成对应的字形
③:由①②我们可以生成一个CTFrame,可以想象成一个字符区域。(我们添加一个视图的时候,要设置视图的frame。同理添加字符的时候,也要设置一个frame)
CTFrame中包含CTLine、CTRun。CTLine即每一行,而CTRun是指一行中连续的一段包含同样属性和方向的文字。CTLine中可以有多个CTRun
四、重定制CTRun
通常情况下图文混排,包含了很多内容,还是需要开发者自己做一些事情,对于每个CTRun,我们可以自己设置它的属性。1.首先,我们看看一个字形是如何定义的:
我们要注意的有3个:
①Bounding
②Ascent
③Descent
2.那么图文混排中的文字和颜色到底是如何绘制上去的呢?
①如果我们要绘制文字: 通过以下方法直接绘制CTFrame
void CTFrameDraw( CTFrameRef frame, CGContextRef context );
②如果我们要绘制图片:
其实只是告诉Core Text有一个地方需要占多大的位置,这样系统就会在指定的地方给出了足够的空间。真正的图像绘制其实还是需要我们自己通过Core Graphic来做。
实际操作中,可以:创建空白占位符,并且设置它的CTRunDelegate信息(通过信息判断图片需要的空间大小)
例如:
static CGFloat ascentCallback(void *ref){ return [(NSNumber*)[(__bridge NSDictionary*)ref objectForKey:@"height"] floatValue]; } static CGFloat descentCallback(void *ref){ return 0; } static CGFloat widthCallback(void* ref){ return [(NSNumber*)[(__bridge NSDictionary*)ref objectForKey:@"width"] floatValue]; } + (NSAttributedString *)parseImageDataFromNSDictionary:(NSDictionary *)dict config:(CTFrameParserConfig*)config { CTRunDelegateCallbacks callbacks; memset(&callbacks, 0, sizeof(CTRunDelegateCallbacks)); callbacks.version = kCTRunDelegateVersion1; callbacks.getAscent = ascentCallback; callbacks.getDescent = descentCallback; callbacks.getWidth = widthCallback; CTRunDelegateRef delegate = CTRunDelegateCreate(&callbacks, (__bridge void *)(dict)); // 使用0xFFFC作为空白的占位符 unichar objectReplacementChar = 0xFFFC; NSString * content = [NSString stringWithCharacters:&objectReplacementChar length:1]; NSDictionary * attributes = [self attributesWithConfig:config]; NSMutableAttributedString * space = [[NSMutableAttributedString alloc] initWithString:content attributes:attributes]; CFAttributedStringSetAttribute((CFMutableAttributedStringRef)space, CFRangeMake(0, 1), kCTRunDelegateAttributeName, delegate); CFRelease(delegate); return space; }
相关文章推荐
- GUI - Web前端开发框架
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 评价ui设计作品好坏的八个标准(界面/交互设计研究)
- 不可修补的 iOS 漏洞可能导致 iPhone 4s 到 iPhone X 永久越狱
- iOS 12.4 系统遭黑客破解,漏洞危及数百万用户
- 每日安全资讯:NSO,一家专业入侵 iPhone 的神秘公司
- [转][源代码]Comex公布JailbreakMe 3.0源代码
- 为Yahoo! UI Extensions Grid增加内置的可编辑器
- Cocos2d-x UI开发之文本类使用实例
- 在IE 浏览器中使用 jquery的fadeIn() 效果 英文字符字体加粗
- UI Events 用户界面事件
- jquery UI Datepicker时间控件的使用方法(基础版)
- 基于jQuery UI CSS Framework开发Widget的经验
- jquery ui 1.7 ui.tabs 动态添加与关闭(按钮关闭+双击关闭)
- jQuery UI设置固定日期选择特效代码分享
- jQuery UI的Dialog无法提交问题的解决方法
- jQuery ui实现动感的圆角渐变网站导航菜单效果代码
- jquery UI Datepicker时间控件的使用方法(终结版)