先看看效果图

这里可以指定显示的宽度,高度随着文字的数量自动增加 看到这些是不是很开心,IM聊天记录基本都是这样的原理。 随着输入的字体自动增加,显示的View的高度自动动态的增加

这里介绍一下coreText,下面的一段话引用自唐巧博客

CoreText 是用于处理文字和字体的底层技术。它直接和 Core Graphics(又被称为 Quartz)打交道。Quartz 是一个 2D 图形渲染引擎,能够处理 OSX 和 iOS 中的图形显示。 Quartz 能够直接处理字体(font)和字形(glyphs),将文字渲染到界面上,它是基础库中唯一能够处理字形的模块。因此,CoreText 为了排版,需要将显示的文本内容、位置、字体、字形直接传递给 Quartz。相比其它 UI 组件,由于 CoreText 直接和 Quartz 来交互,所以它具有高速的排版效果。 下图是 CoreText 的架构图,可以看到,CoreText 处于非常底层的位置,上层的 UI 控件(包括 UILabel,UITextField 以及 UITextView)和 UIWebView 都是基于 CoreText 来实现的。

搞MVC理念来实现

model里面分三个类

YYGFrameParserConfig YYGFrameParser YYGCoreTextDat

Model

1.YYGFrameParserConfig 类

既然要把内容呈现出来,就必须知道内容呈现的内容的一下呈现方式吧! 该类就是干这个的。

需要知道 要显示的宽度

@property(nonatomic, assign) CGFloat width;

需要知道 要显示的字体大小

@property(assign,nonatomic) CGFloat fontSize;

需要知道 要显示的行间距离

@property(assign,nonatomic) CGFloat lineSpace;

需要知道 要显示的字体颜色

@property(strong,nonatomic) UIColor * textColor;

代码如下


@interface YYGFrameParserConfig : NSObject/***  view显示的宽度*/
@property(nonatomic, assign) CGFloat width;/***  字体大小*/
@property(assign,nonatomic) CGFloat fontSize;/***  行间距离*/
@property(assign,nonatomic) CGFloat lineSpace;/***  字体颜色*/
@property(strong,nonatomic) UIColor * textColor;@end--------------------
.m文件
#import "YYGFrameParserConfig.h"@implementation YYGFrameParserConfig-(id)init
{self=[super init];if (self){_width=200.0f;_fontSize=16.0f;_lineSpace=8.0f;_textColor=RGB(108, 108, 108);}return self;
}@end复制代码

2.YYGFrameParser类

我们都知道任何呈现在手机屏幕上的信息都是通过底层图形渲染引擎来完成的,而在UIView里面都是通过CTFrameDraw(CTFrameRef, CGContextRef)来画在画布上的。 所以该类就是生成CTFrameRef它的。 而生成这些要展现在View上的吧!就需要内容!和对内容展现的一些约束,宽度,字体大小啊,而这些在上一个类中我们已经完成啦!! 所以需要如下:

需要内容

需要YYGFrameParserConfig

而最开始介绍过,通过内容可以动态的生产高度这个才是关键啊 所以需要返回高度,和生成的CTFrameRef

返回高度

返回CTFrameRef

居然返回俩参数,好吧直接再弄一个model所以有了下一个model类

本类代码:

#import "YYGFrameParserConfig.h"
#import "YYGCoreTextData.h"@interface YYGFrameParser : NSObject+(YYGCoreTextData *)parseContent:(NSString *)content config:(YYGFrameParserConfig *)config;@end.m文件#import "YYGFrameParser.h"@implementation YYGFrameParser+(YYGCoreTextData *)parseContent:(NSString *)content config:(YYGFrameParserConfig *)config
{NSDictionary * dictionary=[self attributesWithConfig:config];NSAttributedString * string=[[NSAttributedString alloc]initWithString:content attributes:dictionary];// 创建 CTFramesetterRef 实例CTFramesetterRef framesetter=CTFramesetterCreateWithAttributedString((CFAttributedStringRef)string);// 获得要绘制的区域的高度CGSize restrictSize=CGSizeMake(config.width, CGFLOAT_MAX);CGSize coreTextSize=CTFramesetterSuggestFrameSizeWithConstraints(framesetter,CFRangeMake(0, 0), nil, restrictSize, nil);CGFloat textHeight=coreTextSize.height;// 生成 CTFrameRef 实例CTFrameRef frameRef=[self createFrameWithFramesetter:framesetter config:config height:textHeight];// 将生成好的 CTFrameRef 实例和计算好的绘制高度保存到 CoreTextData 实例中,最后返回 CoreTextData 实例YYGCoreTextData *data=[[YYGCoreTextData alloc]init];data.ctFram=frameRef;data.height=textHeight;CFRelease(frameRef);CFRelease(framesetter);return data;}+(NSDictionary *)attributesWithConfig:(YYGFrameParserConfig *)config
{NSMutableDictionary * dict=[NSMutableDictionary dictionary];//1CGFloat fontSize=config.fontSize;CTFontRef fontRef=CTFontCreateWithName((CFStringRef)@"ArialMT", fontSize, NULL);dict[(id)kCTFontAttributeName]=(__bridge id)fontRef;CFRelease(fontRef);//2CGFloat lineSpace=config.lineSpace;const CFIndex kNumberOfSetting=3;CTParagraphStyleSetting theSettings[kNumberOfSetting]={{kCTParagraphStyleSpecifierLineSpacingAdjustment,sizeof(CGFloat),&lineSpace},{kCTParagraphStyleSpecifierMaximumLineSpacing,sizeof(CGFloat),&lineSpace},{kCTParagraphStyleSpecifierMinimumLineSpacing,sizeof(CGFloat),&lineSpace}};CTParagraphStyleRef thePragraphRef=CTParagraphStyleCreate(theSettings, kNumberOfSetting);dict[(id)kCTParagraphStyleAttributeName]=(__bridge id)thePragraphRef;CFRelease(thePragraphRef);//3UIColor * textColor=config.textColor;dict[(id)kCTForegroundColorAttributeName]=(__bridge id)textColor.CGColor;return dict;
}+(CTFrameRef )createFrameWithFramesetter:(CTFramesetterRef)framesetter config:(YYGFrameParserConfig *)config height:(CGFloat)height
{CGMutablePathRef path=CGPathCreateMutable();CGPathAddRect(path, NULL, CGRectMake(0, 0, config.width, height));CTFrameRef frame=CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), path, NULL);CFRelease(path);return frame;
}@end复制代码

3.YYGCoreTextData

它的出现来理由来自于上面的介绍

存储生产的 CTFrameRef

@property(assign,nonatomic) CTFrameRef ctFram;

存储生产的动态生成的高度

@property(assign,nonatomic) CGFloat height;

.m文件
#import "YYGCoreTextData.h"@implementation YYGCoreTextData-(void)setCtFram:(CTFrameRef)ctFram
{if (_ctFram!=ctFram){if (_ctFram!=nil){CFRelease(_ctFram);}CFRetain(ctFram);_ctFram=ctFram;}
}-(void)dealloc
{if (_ctFram!=nil){CFRelease(_ctFram);_ctFram=nil;}}@end复制代码

View

.h文件
@property(strong,nonatomic) YYGCoreTextData * data;.m文件
- (void)drawRect:(CGRect)rect
{[super drawRect:rect];CGContextRef context=UIGraphicsGetCurrentContext();CGContextSetTextMatrix(context, CGAffineTransformIdentity);CGContextTranslateCTM(context, 0, self.bounds.size.height);CGContextScaleCTM(context, 1.0, -1.0);if (self.data){CTFrameDraw(self.data.ctFram, context);}
}复制代码

好吧还需要从写 UIView 的Category方法

在来一个类

#import <UIKit/UIKit.h>@interface UIView (YYGView)-(CGFloat)x;
-(void)setX:(CGFloat)x;-(CGFloat)y;
-(void)setY:(CGFloat)y;-(CGFloat)wide;
-(void)setWide:(CGFloat)wide;-(CGFloat)height;
-(void)setHeight:(CGFloat)height;@end.m文件#import "UIView+YYGView.h"@implementation UIView (YYGView)-(CGFloat)x
{return self.frame.origin.x;
}
-(void)setX:(CGFloat)x
{self.frame=CGRectMake(x, self.y, self.wide, self.height);
}-(CGFloat)y
{return self.frame.origin.y;
}
-(void)setY:(CGFloat)y
{self.frame=CGRectMake(self.x, y, self.wide, self.height);
}-(CGFloat)wide
{return self.frame.size.width;
}
-(void)setWide:(CGFloat)wide
{self.frame=CGRectMake(self.x, self.y, wide, self.height);
}-(CGFloat)height
{return self.frame.size.height;
}
-(void)setHeight:(CGFloat)height
{self.frame=CGRectMake(self.x, self.y, self.wide, height);
}@end复制代码

YYGDisplayView 类

什么Model啊,UIview的category的方法啊,都是为了把东西画在画面上,就是为YYGDisplayView打辅助的,辅助其实很很重要!!!

.m文件#import "YYGDisplayView.h"@implementation YYGDisplayView- (void)drawRect:(CGRect)rect
{[super drawRect:rect];CGContextRef context=UIGraphicsGetCurrentContext();CGContextSetTextMatrix(context, CGAffineTransformIdentity);CGContextTranslateCTM(context, 0, self.bounds.size.height);CGContextScaleCTM(context, 1.0, -1.0);if (self.data){CTFrameDraw(self.data.ctFram, context);}}@end复制代码

Controller现在开始调用了

    YYGFrameParserConfig * config=[[YYGFrameParserConfig alloc]init];config.textColor=[UIColor purpleColor];config.width=self.YYGView.wide;YYGCoreTextData * data=[YYGFrameParser parseContent:@"韩美联合参谋本部3日表示,朝鲜当天上午7时50分在黄海南道殷栗郡一带朝日本海方向发射两枚疑似“芦洞”弹道导弹。其中一枚导弹发射不久便爆炸,另一枚导弹飞越朝鲜境内、最终落在距日本秋田县男鹿半岛250公里的日本专属经济区,总飞行距离约1000公里。日本共同社分析,朝鲜此举除了针对美韩外,还意在制约日本政府。而韩军分析,朝鲜可能通过发射导弹进行武力示威,抗议在韩部署萨德反导系统,并试图助长韩国国内舆论分裂。" config:config];self.YYGView.data=data;self.YYGView.height=data.height;self.YYGView.backgroundColor=[UIColor lightGrayColor];复制代码

iOS中运用coreText 进行文字自适应相关推荐

  1. 在ios中实现图片环绕文字效果

    IOS中有时候需要实现文字环绕图片的效果,用一般的控件很难实现,因为根本就没有支持该属性的控件,折衷的做法就是用UIWebView,在其加载html语言,实现文字的环绕效果. 实现要求:在webVie ...

  2. canvas中的字体在iOS中变小的问题解决

    用canvas做了一个刮奖的js,测试时发现,只有iOS中canvas里的文字变得非常小,都看不清楚,百度上查了一个遍,发现需要在文字样式里添加上small-caps,就可以解决.具体代码: ctx. ...

  3. swif开发iOS中如果要对某块内容加背景图并自适应填充图像

    swif开发iOS中如果要对某块内容加背景图并自适应填充图像 private func setupInfiniteScrollingView() { self.loadMoreView = UIVie ...

  4. ios中常用的第三方库

    下拉刷新 EGOTableViewPullRefresh – 最早的下拉刷新控件. SVPullToRefresh – 下拉刷新控件. MJRefresh – 仅需一行代码就可以为UITableVie ...

  5. iOS即时通讯输入框随字数自适应高度

    代码地址如下: http://www.demodashi.com/demo/13210.html 前言 本人最近在研究socket与聊天界面的UI,在写聊天界面UI的时候是模仿微信的界面其中的文字输入 ...

  6. iOS中UISearchBar(搜索框)使用总结

    2019独角兽企业重金招聘Python工程师标准>>> iOS中UISearchBar(搜索框)使用总结 初始化:UISearchBar继承于UIView,我们可以像创建View那样 ...

  7. ios 中的小技巧 - 总有你想要的 一

    UITableView的Group样式下顶部空白处理 在viewWillAppear里面添加如下代码: //分组列表头部空白处理 CGRect frame = myTableView.tableHea ...

  8. 正则表达式在iOS中的运用

    http://my.oschina.net/u/1245365/blog/376517 http://my.oschina.net/joanfen/blog/415076 摘要 做项目时,经常要检测一 ...

  9. iOS中内存管理的问题——堆和栈

    计算机系统中,运行的应用程序的数据都是保存在内存中的,不同类型的数据,保存的内存区域不同: 1)栈区(stack)由编译器自动分配并释放,一般保存函数的参数值.局部变量 2)堆区(heap)由程序员分 ...

最新文章

  1. 风之语.我看苏州511房产新政
  2. 三层架构项目如何发布_以k8s集群管理为例,大牛教你如何设计优秀项目架构
  3. CNN-3: VGGNet 卷积神经网络模型
  4. optimize table优化mysql例子
  5. Python入门-前言
  6. 万字长文,带你彻底理解EF Core 5的运行机制,让你成为团队中的EF Core专家
  7. 软件测试—软件测试基础知识—测试用例设计的方法之等价类和边界值
  8. java image to base64_Java实现base64图片编码数据转换为本地图片的方法
  9. ubuntu 9.10学习笔记
  10. 史上最简便的可以直接用的登录验证码攻略(前后端都有)
  11. UML建模和开发预演
  12. 只需一个损失函数,一个超参数即可压缩BERT,MSRA提模型压缩新方法
  13. AcWing 1083 Windy数
  14. 如何做字幕?用语音识别生成字幕?
  15. 前端实例1——blog页面(css样式)
  16. 磕磕碰碰三个月,终进字节
  17. C++ opencv计算图像的水平投影,并返回一幅图像
  18. linux下使用find命令全局查找文件
  19. Spring源码分析之AOP源码分析
  20. 渗透测试——信息搜集

热门文章

  1. matlab中for循环设置二维数组,MATLAB中定义赋值一个二维数组
  2. 房价房租比两百比一的道理
  3. php中怎样把图片改大,PHP怎么批量修改图片大小?
  4. 计算机专业262分,一战初试262分!第一名录取对外经贸全日制MPAcc的秘密!
  5. CDR插件开发之CPG插件001 - 什么是CPG插件
  6. 第一学期对于液质、气相处理过程的总结
  7. 剑指Offer(10)有环链表 翻转链表
  8. 计算机英语词汇带英标,小学英语词汇带英标(13页)-原创力文档
  9. 电脑重启bootmgr_开机提示bootmgr is compressed无法启动的方法,看完就明白了
  10. 什么是信道复用?频分复用与时分复用的主要区别是什么?