CoreText使用介绍

一、概述
  
1.CoreText是苹果创建的一个用于文字排版的框架,可以实现文字排版、图文混排等复杂的界面效果。从iOS3.2启用。

2.一个开源工具类-OHAttributedLabel,就是使用CoreText框架实现的,能够实现一个Label中有不同的文字大小、文字颜色、字体以及链接等。  

二、一般使用步骤

1.创建NSMutableAttributedString
NSMutableAttributedString *attributeString = [[NSMutableAttributedString alloc] initWithString:contentString];
                
2.设置文字颜色                
[attributeString addAttribute:(id)kCTForegroundColorAttributeName
                        value:(id)[UIColor darkGrayColor].CGColor 
                        range:NSMakeRange(0, tempArticle.desc.length)];

2.设置字体以及大小                
CTFontRef font = CTFontCreateWithName(CFSTR("Bodoni 72"), contentFontSize, NULL);
[attributeString addAttribute:(id)kCTFontAttributeName value:(id)font range:NSMakeRange(0, [attributeString length])];
CFRelease(font);

4.初始化段落首行缩进样式
CGFloat headIndent = contentFontSize * 2;
CTParagraphStyleSetting headIndentStyle;
headIndentStyle.spec = kCTParagraphStyleSpecifierFirstLineHeadIndent;
headIndentStyle.valueSize = sizeof(headIndent);
headIndentStyle.value = &headIndent;
            
5.初始化文字对齐方式            
CTTextAlignment alignment = kCTJustifiedTextAlignment;
CTParagraphStyleSetting alignmentStyle;
alignmentStyle.spec = kCTParagraphStyleSpecifierAlignment;
alignmentStyle.valueSize = sizeof(alignment);
alignmentStyle.value = &alignment;
            
6.初始化行间距
CGFloat lineSpace = 12.0f;
CTParagraphStyleSetting lineSpaceStyle;
lineSpaceStyle.spec = kCTParagraphStyleSpecifierLineSpacing;
lineSpaceStyle.valueSize = sizeof(lineSpace);
lineSpaceStyle.value = &lineSpace;
            
7.初始化段间距
CGFloat paragraphSpace = 18;
CTParagraphStyleSetting paragraphSpaceStyle;
paragraphSpaceStyle.spec = kCTParagraphStyleSpecifierParagraphSpacing;
paragraphSpaceStyle.valueSize = sizeof(paragraphSpace);
paragraphSpaceStyle.value = &paragraphSpace;
            
8.将段落属性设置到NSMutableAttributedString
CTParagraphStyleSetting settings[4] = {headIndentStyle,alignmentStyle,lineSpaceStyle,paragraphSpaceStyle};
CTParagraphStyleRef paragraphStyle = CTParagraphStyleCreate((const CTParagraphStyleSetting*)&settings,4);
[attributeString addAttribute:(id)kCTParagraphStyleAttributeName 
                        value:(id)paragraphStyle range:NSMakeRange(0, [attributeString length])];
CFRelease(paragraphStyle);

9.创建CTFramesetterRef            
CTFramesetterRef frameSetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)attributeString);
            
10.绘制之前,翻转绘图坐标系
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetTextMatrix(context, CGAffineTransformIdentity);
CGContextTranslateCTM(context, 0, self.bounds.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
            
11.按照区域进行绘制       
CFIndex startIndex = 0; 
NSInteger pathCount = 0;
while (YES) {
   //构建绘图区域
   CGMutablePathRef columnPath = CGPathCreateMutable();
   CGPathAddRect(columnPath, NULL,
      CGRectMake(20 + (pathCount%columnNum) * ((768-(columnNum+1)*20)/columnNum + 20), 50, (768-(columnNum+1)*20)/columnNum, 904));
   //构建内容窗体
   CTFrameRef frame = CTFramesetterCreateFrame(frameSetter, CFRangeMake(startIndex,0), columnPath, NULL);
   //绘制内容窗体
   CTFrameDraw(frame, context);
   //计算当前显示结束位置的字符索引
   CFRange currRange = CTFrameGetVisibleStringRange(frame);
   startIndex = startIndex + currRange.length;
   //释放
   CGPathRelease(columnPath);
   CFRelease(frame);
   //计数增加     
   pathCount++;
   //结束
   if (startIndex == [attributeString length]) {
      break;
   }
}

12.按照行进行绘制
CFIndex start = 0;
while (YES) {
   //判断是否绘制完毕
   if (start == attributeString.length) {
      break;
   }
   //根据内容、开始索引位置和绘制区域的宽度,返回推荐的换行位置索引
   CFIndex count = CTTypesetterSuggestLineBreak(frameSetter, start, pageWidth);
   //创建一个新行
   CTLineRef line = CTTypesetterCreateLine(frameSetter, CFRangeMake(start, count));
   //获取新行的排版属性     
   CGFloat ascent;
   CGFloat descent;
   CGFloat leading;
   CTLineGetTypographicBounds(line, &ascent,  &descent, &leading);
   //计算新行的Y值                 
   imageY = imageY - lineSpace - ascent - descent - leading;
   //绘制行                 
   CGContextSetTextPosition(currContext, 0.0f, imageY);
   CTLineDraw(line, currContext);
   //释放行对象                 
   CFRelease(line);
   //更改当前绘制的位置索引                 
   start += count;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/499898.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

编程规范:长函数的思考

在工作,我们应该都不想看到非常的长函数。对于一个运行5年左右的项目,极有可能出现这种情况。由于长函数的长、if/else嵌套,导致代码的可读性非常差,这对于项目的维护和开发带来了极大的困难。所以我们应该避免写长函数&#xff0…

用redis实现延迟队列

现在在用的redis实现延迟队列的主流程

iPhone各版本屏幕尺寸

设备宽高对角线逻辑分辨率(point)Scale Factor设备分辨率(pixel)PPI iPhoneWidthHeightDiagonal 3GS2.4 inches (62.1 mm)4.5 inches (115.5 mm)3.5-inch320x4801x320x480163 4(s)2.31 inches (58.6 mm)4.5 inches (115.2 mm)3.5-inch320x4802x640x960326 5c2.33 inches (59.2…

maven更新快照不起作用的解决方法

问题:maven的快照包更新后,调用方使用idea点下面这个地方更新maven,并没有拉到最新的快照 解决方法1 删除本地仓库的快照包,再重新拉一次 解决方法2 下图,这里点进去 下图,这个勾上就行了,再…

iOS中frame和Bounds之间的区别

frame frame是每个view必备的属性,代表的是当前视图的位置和大小,没有设置他,当前视图是看不到的。位置需要有参照物才能确定,数学中我们用坐标系来确定坐标系中的某个点的位置,iOS中有他特有的坐标系,如下…

[数据库]-----mysql数据的冷热分离 第二版

1.前提 这次数据库的冷热分离算是第二次做了 其实之前已经做过一次冷热分离了,涉及到数据库复制时,当时是趋近于业务的(后面会详细讲),整体来讲不是很好用,这次算是重构了吧 做的最终结果还是和前一次一样: 数据库中的订单数据,是每时每刻都在增加 我们认为3个月以内的数据,用…

URL结构

一、概念 URL:统一资源定位符 (Uniform Resource Locator, URL)。 完整的URL由这几个部分构成:scheme://host:port/path?query#hash: scheme:通信协议,常用的有http、https、ftp、mailto等。 host:主机…

[数据库]-----记一次mysql分库的操作(冷热分离)

前提: 1.原有库是mysql数据库,已经根据用户pin分片 2.每片是一主两从 3.主表已经分过表了 4.数据库所在服务器为4C8G 5.库中数据量已经超过千万,而且以每天3万多的数据持续增长,将来每天或许会更多 6.库内数据为订单数据,每时每刻都有新的订单产生,每个…

使用OC进行iOS截屏,同时保证清晰度

一般情况下我们使用如下代码进行截屏:UIWindow *screenWindow [[UIApplication sharedApplication] keyWindow]; UIGraphicsBeginImageContext(screenWindow.frame.size); [screenWindow.layer renderInContext:UIGraphicsGetCurrentContext()]; UIImage *screenIm…

[python]---从java到python(02)---多线程,队列

多线程测试 #!/usr/bin/env python # -*- coding:utf-8 -*-import threading import timeclass A(threading.Thread):def __init__(self):# 初始化改线程threading.Thread.__init__(self)def run(self):# 该线程要执行的程序内容for i in range(3):print("我是线程A&quo…

将iOS默认上下文坐标系改变为Quartz通常坐标系

由于iOS的UIKit默认的坐标系的原点处于视图的左上角,而Quartz的通常坐标系中的原点位于左下角。当我们使用UIKit的坐标操作CGContextRef的时候,绘制出来的图片是上下颠倒的。因此我们在使用Qaurtz处理图形的时候,往往需要将坐标系转为与Quart…

[python]---从java到python(03)---爬虫

1.简单网页 #!/usr/bin/env python # -*- coding:utf-8 -*-import urllib.requestfile urllib.request.urlopen("https://www.jd.com") data file.read() # dataline file.readline() print(data)fhandle open("E:/python/1_1.html", "wb"…

iOS网络请求认证挑战

一、引言 Http请求中认证挑战相关的代理如下: 1.将要发送一个认证挑战的请求 - connection:willSendRequestForAuthenticationChallenge:2.是否能够对一个保护空间进行认证(已废弃)- connection:canAuthenticateAgainstProtectionSpace:3.…

大数据相关整理

1.hdfs 1.1.namenode 所有文件的读写入口,用来保存文件的元信息 元信息包括: fsimage文件:文件权限信息文件在block块的偏移量文件的位置信息 editlogs文件:对文件的写操作日志文件写日志指令,为了安全同步&#xf…

OC编码规范

一、命名规范 1.类: (1)首字母大写,后续单词首字母大写。 (2)类名末尾要包含此类的类型,比如RootView,RootViewController。 2.属性 (1)属性名称首字母小写,后续首字母大写; (2)使用property,要保持必要的空格&#xf…

数据库---mysql的索引和引擎

mysql 的索引和引擎 mysql的数据都是存放在磁盘上的,都说索引会使查询变快,那么肯定是索引用了特殊的数据结构。 常见的数据结构有: hash hash就是咱们在hashMap中的那个hash,用hash确实快,而且时间复杂度是O&#x…

SQLite内置表SQLITE_MASTER

一、概述1.SQLite数据库中有一个内置表,名为SQLITE_MASTER,此表中存储着当前数据库中所有表的相关信息,比如表的名称、用于创建此表的sql语句、索引、索引所属的表、创建索引的sql语句等。2.SQLITE_MASTER表示只读的,只能对他进行…

redis单线程为什么还快的个人解释

面试的时候, 面试官问,redis是单线程还是多线程 答:单线程 面试官再问,单线程,为什么还快呢?不应该是多线程才更快吗?那这是不是有什么矛盾啊? 答:啊?&#x…

CDN的实现原理

一、传统模式 在描述CDN的实现原理前,让我们先看传统的未加缓存服务的访问过程,以便了解CDN缓存访问方式与未加缓存访问方式的差别: 用户提交域名→浏览器对域名进行解释→得到目的主机的IP地址→根据IP地址访问发出请求→得到请求数据并回复…

数据库---事务的隔离级别

首先,我们下面说的数据库事务,都是使用INNODB引擎的结果。 MYISAM是没有事务的,也就没有下面这些说法。 1.数据库事务的四大特性: 原子性:事务包含的所有数据库操作要么全部成功,要不全部失败回滚一致性&…