赞
踩
关于CoreText基础,推崇紫色大番薯的《CoreText原理及基本使用方法》一文,有珠玉在前,我就不再详述。
CoreText是用于处理文字和字体的底层技术,多用于富文本排版布局。IOS6.0以后UILabel、UITextField增加了新的富文本处理方式,使用起来要比CoreText友好的多。现在网上很多CoreText应用实例,都可以使用UILabel、UITextField更加简便的给予实现。但是总有一些复杂的问题必须用到CoreText,这里分享一个我遇到过实例。
在view中自动排版展示文档格式储存的试卷,文档的首行为标题,填空题需要直接在题目中填写答案, 选择题的选项以按钮的形式展现。
原始文件实例
ETHNOGRAPHY IN BUSINESS
1. It can be used in business:
• to investigate customer needs and ……………………
• to help …………………… develop new designs
2. What change in the road network is known to have benefited the town most?
○ the construction of a bypass
○ the development of cycle paths
○ the banning of cars from certain streets
最终显示效果
1. 把文档转换为富文本
2. 使用CoreText绘制富文本
3. 确定输入框,选项位置
4. 创建UITextField作为输入框,创建UIButton作为选项,
以下信息要加入到富文本之中:
- -(NSMutableAttributedString *)getMutableAttributedString{
- NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:_text];
- NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
- [paragraphStyle setLineSpacing:5];
- [paragraphStyle setParagraphSpacingBefore:8];
- [attributedString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, [_text length])];
- //第一行为标题
- NSRange firstLineRange=[_text lineRangeForRange:NSMakeRange(0, 1)];
- [attributedString addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:20] range:firstLineRange]; // 6.0+
- //………………处添加UITextView作为输入框
- NSRange inputRange=[_text rangeOfString:@"………………"];
- while(inputRange.length>0){
- [attributedString addAttribute:(id)@"FTCoreTextDataName" value:(id)@"input" range:inputRange];
- if (inputRange.length+inputRange.location==_text.length) {
- inputRange=NSMakeRange(0,0);
- } else {
- inputRange=[_text rangeOfString:@"………………" options:0 range:NSMakeRange(inputRange.location+1,_text.length-inputRange.length-inputRange.location-1)];
- }
- }
- //○开始行为按钮,
- NSRange buttonRange=[_text rangeOfString:@"○"];
- while(buttonRange.length>0){
- [attributedString addAttribute:(id)@"FTCoreTextDataName" value:(id)@"button" range:buttonRange];
- buttonRange=[_text rangeOfString:@"○" options:0 range:NSMakeRange(buttonRange.location+1,_text.length-buttonRange.length-buttonRange.location-1)];
- }
- return attributedString;
-
- }
- //获取当前上下文
- CGContextRef context = UIGraphicsGetCurrentContext();
- //填充背景色
- [self.backgroundColor setFill];
- CGContextFillRect(context, rect);
- //翻转坐标系步骤
- //设置当前文本矩阵
- CGContextSetTextMatrix(context, CGAffineTransformIdentity);
- //文本沿y轴移动
- CGContextTranslateCTM(context, 0, self.bounds.size.height);
- //文本翻转成为CoreText坐标系
- CGContextScaleCTM(context, 1.0, -1.0);
- //获取NSMutableAttributedString
- NSMutableAttributedString *attributedString=[self getMutableAttributedString];
- //根据AttString生成CTFramesetterRef
- CTFramesetterRef ctFramesetter = CTFramesetterCreateWithAttributedString((CFMutableAttributedStringRef)attributedString);
- //创建绘制区域
- CGMutablePathRef path = CGPathCreateMutable();
- CGRect bounds = CGRectMake(0.0, 0.0, self.bounds.size.width, self.bounds.size.height);
- CGPathAddRect(path, NULL, bounds);
- //绘制文本
- CTFrameRef ctFrame = CTFramesetterCreateFrame(ctFramesetter,CFRangeMake(0, 0), path, NULL);
- CTFrameDraw(ctFrame, context);
遍历每一个CTRunRef,查找我们在富文本中加入的标记
- for (int i = 0; i < CFArrayGetCount(lines); i++) {
- CTLineRef line = CFArrayGetValueAtIndex(lines, i);
- CGFloat lineAscent;
- CGFloat lineDescent;
- CGFloat lineLeading;
- CTLineGetTypographicBounds(line, &lineAscent, &lineDescent, &lineLeading);
- CFArrayRef runs = CTLineGetGlyphRuns(line);
- //遍历每一个CTRunRef
- for (int j = 0; j < CFArrayGetCount(runs); j++) {
- CGPoint lineOrigin = lineOrigins[i];
- CTRunRef run = CFArrayGetValueAtIndex(runs, j);
- NSDictionary* attributes = (NSDictionary*)CTRunGetAttributes(run);
- const CGPoint *point=CTRunGetPositionsPtr(run);
-
- NSString *attributeName = [attributes objectForKey:@"FTCoreTextDataName"];
- if ([attributeName isEqualToString:@"input"]) {
- //输入框标记
- 。。。。。。
- }else if ([attributeName isEqualToString:@"button"]){
- //按钮标记
- 。。。。。。 }
- }
- }
此处需注意CoreText坐标系和UIKit坐标系的换算,新建控件使用的是UIKit坐标系。
创建输入框
- UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(point[0].x+7, self.frame.size.height-lineOrigin.y-14, 150.0f, 20.0f)];
- [textField setBorderStyle:UITextBorderStyleNone]; //外框类型
- textField.placeholder = @""; //默认显示的字
- textField.font=[UIFont fontWithName:@"TimesNewRomanPSMT" size:12.f];
- textField.textColor=[UIColor blueColor];
- [self addSubview:textField];
创建按钮
- UIButton *button =[[UIButton alloc]initWithFrame:CGRectMake(point[0].x-5, self.frame.size.height-lineOrigin.y-16, 250, 22.0f)];
- UIColor *ucolor=[UIColor lightGrayColor];
- [button.layer setMasksToBounds:YES];
- [button.layer setCornerRadius:7.0]; //设置矩圆角半径
- [button.layer setBorderWidth:1.0]; //边框宽度
- [button.layer setBorderColor:ucolor.CGColor];//边框颜色
- [self addSubview:button];
- // 为UIButton关联响应事件
- [self.delegate addCoreTextViewObject:button type:@"button"];
完整drawRect()代码
- - (void)drawRect:(CGRect)rect {
- //获取当前上下文
- CGContextRef context = UIGraphicsGetCurrentContext();
- //填充背景色
- [self.backgroundColor setFill];
- CGContextFillRect(context, rect);
- //翻转坐标系步骤
- //设置当前文本矩阵
- CGContextSetTextMatrix(context, CGAffineTransformIdentity);
- //文本沿y轴移动
- CGContextTranslateCTM(context, 0, self.bounds.size.height);
- //文本翻转成为CoreText坐标系
- CGContextScaleCTM(context, 1.0, -1.0);
- //获取NSMutableAttributedString
- NSMutableAttributedString *attributedString=[self getMutableAttributedString];
- //根据AttString生成CTFramesetterRef
- CTFramesetterRef ctFramesetter = CTFramesetterCreateWithAttributedString((CFMutableAttributedStringRef)attributedString);
- //创建绘制区域
- CGMutablePathRef path = CGPathCreateMutable();
- CGRect bounds = CGRectMake(0.0, 0.0, self.bounds.size.width, self.bounds.size.height);
- CGPathAddRect(path, NULL, bounds);
- //绘制文本
- CTFrameRef ctFrame = CTFramesetterCreateFrame(ctFramesetter,CFRangeMake(0, 0), path, NULL);
- CTFrameDraw(ctFrame, context);
- //获取CTLine数组
- CFArrayRef lines = CTFrameGetLines(ctFrame);
- CGPoint lineOrigins[CFArrayGetCount(lines)];
- CTFrameGetLineOrigins(ctFrame, CFRangeMake(0, 0), lineOrigins);
- //遍历每一个CTline
- for (int i = 0; i < CFArrayGetCount(lines); i++) {
- CTLineRef line = CFArrayGetValueAtIndex(lines, i);
- CGFloat lineAscent;
- CGFloat lineDescent;
- CGFloat lineLeading;
- CTLineGetTypographicBounds(line, &lineAscent, &lineDescent, &lineLeading);
- CFArrayRef runs = CTLineGetGlyphRuns(line);
- //遍历每一个CTRunRef
- for (int j = 0; j < CFArrayGetCount(runs); j++) {
- CGPoint lineOrigin = lineOrigins[i];
- CTRunRef run = CFArrayGetValueAtIndex(runs, j);
- NSDictionary* attributes = (NSDictionary*)CTRunGetAttributes(run);
- const CGPoint *point=CTRunGetPositionsPtr(run);
-
- NSString *attributeName = [attributes objectForKey:@"FTCoreTextDataName"];
- if ([attributeName isEqualToString:@"input"]) {
- //添加输入框
- if (createObjectMode) {
- UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(point[0].x+7, self.frame.size.height-lineOrigin.y-14, 150.0f, 20.0f)];
- [textField setBorderStyle:UITextBorderStyleNone]; //外框类型
- textField.placeholder = @""; //默认显示的字
- textField.font=[UIFont fontWithName:@"TimesNewRomanPSMT" size:12.f];
- textField.textColor=[UIColor blueColor];
- [self addSubview:textField];
- // 为UITextView关联响应事件
- [self.delegate addCoreTextViewObject:textField type:@"input"];
- }else{
- CGRect frame=CGRectMake(point[0].x+7, self.frame.size.height-lineOrigin.y-14, 150.0f, 20.0f);
- [self.delegate resetObjectFrame:frame type:@"input"];
- }
-
- }else if ([attributeName isEqualToString:@"button"]){
- //添加按钮
- if (createObjectMode) {
- UIButton *button =[[UIButton alloc]initWithFrame:CGRectMake(point[0].x-5, self.frame.size.height-lineOrigin.y-16, 250, 22.0f)];
- UIColor *ucolor=[UIColor lightGrayColor];
- [button.layer setMasksToBounds:YES];
- [button.layer setCornerRadius:7.0]; //设置矩圆角半径
- [button.layer setBorderWidth:1.0]; //边框宽度
- [button.layer setBorderColor:ucolor.CGColor];//边框颜色
- [self addSubview:button];
- // 为UIButton关联响应事件
- [self.delegate addCoreTextViewObject:button type:@"button"];
- }else{
- CGRect frame=CGRectMake(point[0].x-5, self.frame.size.height-lineOrigin.y-16, 250, 22.0f);
- [self.delegate resetObjectFrame:frame type:@"button"];
-
- }
- }
- }
- }
-
- if (createObjectMode){
- createObjectMode=NO;
- }
-
- CFRelease(ctFrame);
- CFRelease(path);
- CFRelease(ctFramesetter);
- }
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。