美文网首页
https://github.com/ibireme/YYTex

https://github.com/ibireme/YYTex

作者: 野咪咕 | 来源:发表于2021-11-30 12:02 被阅读0次

中文介绍

功能强大的 iOS 富文本编辑与显示框架。

(该项目是 YYKit 组件之一)

特性

API 兼容 UILabel 和 UITextView

支持高性能的异步排版和渲染

扩展了 CoreText 的属性以支持更多文字效果

支持 UIImage、UIView、CALayer 作为图文混排元素

支持添加自定义样式的、可点击的文本高亮范围

支持自定义文本解析 (内置简单的 Markdown/表情解析)

支持文本容器路径、内部留空路径的控制

支持文字竖排版,可用于编辑和显示中日韩文本

支持图片和富文本的复制粘贴

文本编辑时,支持富文本占位符

支持自定义键盘视图

撤销和重做次数的控制

富文本的序列化与反序列化支持

支持多语言,支持 VoiceOver

支持 Interface Builder

全部代码都有文档注释

架构

YYText 和 TextKit 架构对比

文本属性

YYText 原生支持的属性

DemoAttribute NameClass

TextAttachmentYYTextAttachment

TextHighlightYYTextHighlight

TextBindingYYTextBinding

TextShadow

TextInnerShadow

YYTextShadow

TextBorderYYTextBorder

TextBackgroundBorderYYTextBorder

TextBlockBorderYYTextBorder

TextGlyphTransformNSValue(CGAffineTransform)

TextUnderlineYYTextDecoration

TextStrickthroughYYTextDecoration

TextBackedStringYYTextBackedString

YYText 支持的 CoreText 属性

DemoAttribute NameClass

Font UIFont(CTFontRef)

Kern NSNumber

StrokeWidth NSNumber 

StrokeColor CGColorRef 

Shadow NSShadow 

Ligature NSNumber 

VerticalGlyphForm NSNumber(BOOL) 

WritingDirection NSArray(NSNumber) 

RunDelegate CTRunDelegateRef 

TextAlignment NSParagraphStyle 

(NSTextAlignment) 

LineBreakMode NSParagraphStyle 

(NSLineBreakMode) 

LineSpacing NSParagraphStyle 

(CGFloat) 

ParagraphSpacing 

ParagraphSpacingBefore 

NSParagraphStyle 

(CGFloat) 

FirstLineHeadIndent NSParagraphStyle 

(CGFloat) 

HeadIndent NSParagraphStyle 

(CGFloat) 

TailIndent NSParagraphStyle 

(CGFloat) 

MinimumLineHeight NSParagraphStyle 

(CGFloat) 

MaximumLineHeight NSParagraphStyle 

(CGFloat) 

LineHeightMultiple NSParagraphStyle 

(CGFloat) 

BaseWritingDirection NSParagraphStyle 

(NSWritingDirection) 

DefaultTabInterval 

TabStops 

NSParagraphStyle 

CGFloat/NSArray(NSTextTab)

用法

基本用法

//YYLabel (和 UILabel 用法一致)YYLabel *label = [YYLabelnew];

label.frame = ...

label.font = ...

label.textColor = ...

label.textAlignment = ...

label.lineBreakMode = ...

label.numberOfLines = ...

label.text = ...

//YYTextView (和 UITextView 用法一致)

YYTextView *textView = [YYTextViewnew];

textView.frame = ...

textView.font = ...

textView.textColor = ...

textView.dataDetectorTypes = ...

textView.placeHolderText = ...

textView.placeHolderTextColor = ...

textView.delegate = ...

属性文本

//1. 创建一个属性文本

NSMutableAttributedString*text = [[NSMutableAttributedStringalloc]initWithString:@"Some Text, blabla..."];

//2. 为文本设置属性

text.yy_font = [UIFont boldSystemFontOfSize:30];

text.yy_color = [UIColor blueColor];

[text yy_setColor:[UIColor redColor] range:NSMakeRange(0,4)];

text.yy_lineSpacing =10;

//3. 赋值到 YYLabel 或 YYTextView

YYLabel *label = [YYLabel new];

label.frame = ...

label.attributedString = text;    

YYTextView *textView = [YYTextView new];

textView.frame = ...

textView.attributedString = text;

文本高亮

你可以用一些已经封装好的简便方法来设置文本高亮:

[text yy_setTextHighlightRange:range color:[UIColor blueColor] backgroundColor:[UIColor grayColor] tapAction:^(UIView *containerView,NSAttributedString*text,NSRangerange,CGRectrect){

NSLog(@"tap text range:..."); 

 }];

或者用更复杂的办法来调节文本高亮的细节:

//1. 创建一个"高亮"属性,当用户点击了高亮区域的文本时,"高亮"属性会替换掉原本的属性

YYTextBorder *border = [YYTextBorder borderWithFillColor:[UIColor grayColor] cornerRadius:3];  

 YYTextHighlight *highlight = [YYTextHighlight new];

[highlight setColor:[UIColor whiteColor]];

[highlight setBackgroundBorder:highlightBorder];

highlight.tapAction = ^(UIView *containerView,NSAttributedString*text,NSRange range,CGRect rect) {

NSLog(@"tap text range:...");

//你也可以把事件回调放到 YYLabel 和 YYTextView 来处理。

};

//2. 把"高亮"属性设置到某个文本范围

[attributedText yy_setTextHighlight:highlight range:highlightRange];

//3. 把属性文本设置到 YYLabel 或 YYTextView

YYLabel *label = ...

label.attributedText = attributedText    

YYTextView *textView = ...

textView.attributedText = ...

//4. 接受事件回调

label.highlightTapAction = ^(UIView *containerView,NSAttributedString*text,NSRangerange,CGRect rect) {

NSLog(@"tap text range:...");

};

label.highlightLongPressAction = ^(UIView *containerView,NSAttributedString*text,NSRange range,CGRect rect) {

NSLog(@"long press text range:...");

};    

@UITextViewDelegate

- (void)textView:(YYTextView *)textView didTapHighlight:(YYTextHighlight *)highlight inRange:(NSRange)characterRange rect:(CGRect)rect {

NSLog(@"tap text range:...");

}

- (void)textView:(YYTextView *)textView didLongPressHighlight:(YYTextHighlight *)highlight inRange:(NSRange)characterRange rect:(CGRect)rect {

NSLog(@"long press text range:...");

}

图文混排

NSMutableAttributedString*text = [NSMutableAttributedString new];

UIFont *font = [UIFont systemFontOfSize:16];

NSMutableAttributedString*attachment =nil;

//嵌入 UIImage

UIImage *image = [UIImage imageNamed:@"dribbble64_imageio"];

attachment = [NSMutableAttributedString yy_attachmentStringWithContent:image contentMode:UIViewContentModeCenter attachmentSize:image.size alignToFont:font alignment:YYTextVerticalAlignmentCenter];

[text appendAttributedString:attachment];

//嵌入 UIView

UISwitch *switcher = [UISwitch new];

[switcher sizeToFit];

attachment = [NSMutableAttributedString yy_attachmentStringWithContent:switcher contentMode:UIViewContentModeBottomattachmentSize:switcher.size alignToFont:font alignment:YYTextVerticalAlignmentCenter];

[text appendAttributedString:attachment];

//嵌入 CALayer

CASharpLayer *layer = [CASharpLayer layer];

layer.path = ...

attachment = [NSMutableAttributedString yy_attachmentStringWithContent:layer contentMode:UIViewContentModeBottom attachmentSize:switcher.size alignToFont:font alignment:YYTextVerticalAlignmentCenter];

[text appendAttributedString:attachment];

文本布局计算

NSAttributedString*text = ...

CGSizesize = CGSizeMake(100, CGFLOAT_MAX);

YYTextLayout *layout = [YYTextLayout layoutWithContainerSize:size text:text];

//获取文本显示位置和大小

layout.textBoundingRect;//get bounding rect

layout.textBoundingSize;//get bounding size

//查询文本排版结果

[layout lineIndexForPoint:CGPointMake(10,10)];

[layout closestLineIndexForPoint:CGPointMake(10,10)];

[layout closestPositionToPoint:CGPointMake(10,10)];

[layout textRangeAtPoint:CGPointMake(10,10)];

[layout rectForRange:[YYTextRange rangeWithRange:NSMakeRange(10,2)]];

[layout selectionRectsForRange:[YYTextRange rangeWithRange:NSMakeRange(10,2)]];

//显示文本排版结果

YYLabel *label = [YYLabel new];

label.size = layout.textBoundingSize;

label.textLayout = layout;

文本行位置调整

//由于中文、英文、Emoji 等字体高度不一致,或者富文本中出现了不同字号的字体,

//可能会造成每行文字的高度不一致。这里可以添加一个修改器来实现固定行高,或者自定义文本行位置。

//简单的方法:

//1. 创建一个文本行位置修改类,实现 `YYTextLinePositionModifier` 协议。

//2. 设置到 Label 或 TextView。

YYTextLinePositionSimpleModifier *modifier = [YYTextLinePositionSimpleModifier new];

modifier.fixedLineHeight =24;

YYLabel *label = [YYLabel new];

label.linePositionModifier = modifier;

//完全控制:

YYTextLinePositionSimpleModifier *modifier = [YYTextLinePositionSimpleModifier new];

modifier.fixedLineHeight =24;

YYTextContainer *container = [YYTextContainer new];

container.size = CGSizeMake(100, CGFLOAT_MAX);

container.linePositionModifier = modifier;

YYTextLayout *layout = [YYTextLayout layoutWithContainer:container text:text];

YYLabel *label = [YYLabel new];

label.size = layout.textBoundingSize;

label.textLayout = layout;

异步排版和渲染

//如果你在显示字符串时有性能问题,可以这样开启异步模式:

YYLabel *label = ...

label.displaysAsynchronously =YES;

//如果需要获得最高的性能,你可以在后台线程用 `YYTextLayout` 进行预排版:

YYLabel *label = [YYLabel new];

label.displaysAsynchronously =YES;//开启异步绘制

label.ignoreCommonProperties =YES;//忽略除了 textLayout 之外的其他属性

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{//创建属性字符串

NSMutableAttributedString*text = [[NSMutableAttributedString alloc]initWithString:@"Some Text"];  

 text.yy_font= [UIFont systemFontOfSize:16]; 

 text.yy_color= [UIColor grayColor];  

 [text yy_setColor:[UIColor redColor] range:NSMakeRange(0,4)];

//创建文本容器

YYTextContainer *container = [YYTextContainer new]; 

 container.size=CGSizeMake(100, CGFLOAT_MAX);  

 container.maximumNumberOfRows=0;

//生成排版结果

YYTextLayout *layout = [YYTextLayout layoutWithContainer:container text:text];

dispatch_async(dispatch_get_main_queue(), ^{      

 label.size= layout.textBoundingSize;     

 label.textLayout= layout;  

 });

});

文本容器控制

YYLabel *label = ...

label.textContainerPath = [UIBezierPath bezierPathWith...];

label.exclusionPaths = @[[UIBezierPath bezierPathWith...];,...];

label.textContainerInset = UIEdgeInsetsMake(...);

label.verticalForm =YES/NO;    

YYTextView *textView = ...

textView.exclusionPaths = @[[UIBezierPath bezierPathWith...];,...];

textView.textContainerInset = UIEdgeInsetsMake(...);

textView.verticalForm =YES/NO;

文本解析

//1. 创建一个解析器//内置简单的表情解析

YYTextSimpleEmoticonParser *parser = [YYTextSimpleEmoticonParser new];

NSMutableDictionary*mapper = [NSMutableDictionary new];

mapper[@":smile:"] = [UIImage imageNamed:@"smile.png"];

mapper[@":cool:"] = [UIImage imageNamed:@"cool.png"];

mapper[@":cry:"] = [UIImage imageNamed:@"cry.png"];

mapper[@":wink:"] = [UIImage imageNamed:@"wink.png"];

parser.emoticonMapper = mapper;

//内置简单的 markdown 解析

YYTextSimpleMarkdownParser *parser = [YYTextSimpleMarkdownParser new];

[parsersetColorWithDarkTheme];

//实现 `YYTextParser` 协议的自定义解析器

MyCustomParser *parser = ...

//2. 把解析器添加到 YYLabel 或 YYTextView

YYLabel *label = ...

label.textParser = parser;    

YYTextView *textView = ...

textView.textParser = parser;

Debug

//设置一个全局的 debug option 来显示排版结果。

YYTextDebugOption *debugOptions = [YYTextDebugOption new];

debugOptions.baselineColor = [UIColor redColor];

debugOptions.CTFrameBorderColor = [UIColor redColor];

debugOptions.CTLineFillColor = [UIColor colorWithRed:0.000green:0.463blue:1.000alpha:0.180];

debugOptions.CGGlyphBorderColor = [UIColor colorWithRed:1.000green:0.524blue:0.000alpha:0.200];

[YYTextDebugOption setSharedDebugOption:debugOptions];

更多示例

查看演示工程 Demo/YYTextDemo.xcodeproj:

安装

CocoaPods

在 Podfile 中添加 pod 'YYText'。

执行 pod install 或 pod update。

导入 <YYText/YYText.h>。

Carthage

在 Cartfile 中添加 github "ibireme/YYText"。

执行 carthage update --platform ios 并将生成的 framework 添加到你的工程。

导入 <YYText/YYText.h>。

手动安装

下载 YYText 文件夹内的所有内容。

将 YYText 内的源文件添加(拖放)到你的工程。

链接以下 frameworks:

UIKit

CoreFoundation

CoreText

QuartzCore

Accelerate

MobileCoreServices

导入 YYText.h。

注意

你可以添加 YYImage 或 YYWebImage 到你的工程,以支持动画格式(GIF/APNG/WebP)的图片。

相关文章

网友评论

      本文标题:https://github.com/ibireme/YYTex

      本文链接:https://www.haomeiwen.com/subject/uxcdxrtx.html