YYText使用篇(一)
版本記錄
版本號 | 時間 |
---|---|
V1.0 | 2017.06.04 |
前言
YYText是一個專門處理文字的框架,作者是國內的一個技術大牛,他有很多框架,還有我們知道的YYModel、YYText、YYCache等,這裡我們就先說一下YYText。
一、YYText作者
我們先看一下YYText的作者,以及他的其他框架。

YYText
二、YYText框架特點
YYText具有如下特點:
- 相容UILabel和UITextView API框架
- 高效能非同步文字佈局和渲染
- CoreText可擴充套件,擁有更多的文字效果
- 具有UIImage,UIView和CALayer富文字效果
- 自定義高亮文字允許使用者互動
- 文字解析器(內建markdown/表情解析器)
- 支援文字容器路徑和排除路徑
- 支援垂直表單佈局(對於CJK文字)
- 支援影象和特性文字的貼上和賦值
- 支援特性文字佔位符
- 支援自定義鍵盤檢視
- 撤銷和重新控制
- 支援特性文字的歸檔和解檔
- 支援多語言和VoiceOver
- 支援Interface Builder
- 技術文件齊備
三、YYText vs TextKit結構
下面我們看一下這兩種框架的結構。

YYText vs TextKit結構
四、YYText支援的文字特性
1.YYText原生支援的特性
示例1

示例1
示例2

示例2
示例3

示例3
示例4

示例4
示例5

示例5
示例6

示例6
示例7

示例7
示例8

示例8-1

示例8-2

示例8-3
2.YYText 支援的 CoreText 屬性
<tr> <td></td> <td> TextAlignment </td> <td> NSParagraphStyle <br/>(NSTextAlignment) </td> </tr> <tr> <td></td> <td> LineBreakMode </td> <td> NSParagraphStyle <br/>(NSLineBreakMode) </td> </tr> <tr> <td></td> <td> LineSpacing </td> <td> NSParagraphStyle <br/>(CGFloat) </td> </tr> <tr> <td></td> <td> ParagraphSpacing <br/> ParagraphSpacingBefore </td> <td> NSParagraphStyle <br/>(CGFloat) </td> </tr> <tr> <td></td> <td> FirstLineHeadIndent </td> <td> NSParagraphStyle <br/>(CGFloat) </td> </tr> <tr> <td></td> <td> HeadIndent </td> <td> NSParagraphStyle <br/>(CGFloat) </td> </tr> <tr> <td></td> <td> TailIndent </td> <td> NSParagraphStyle <br/>(CGFloat) </td> </tr> <tr> <td></td> <td> MinimumLineHeight </td> <td> NSParagraphStyle <br/>(CGFloat) </td> </tr> <tr> <td></td> <td> MaximumLineHeight </td> <td> NSParagraphStyle <br/>(CGFloat) </td> </tr> <tr> <td></td> <td> LineHeightMultiple </td> <td> NSParagraphStyle <br/>(CGFloat) </td> </tr> <tr> <td></td> <td> BaseWritingDirection </td> <td> NSParagraphStyle <br/>(NSWritingDirection) </td> </tr> <tr> <td></td> <td> DefaultTabInterval <br/> TabStops </td> <td> NSParagraphStyle <br/>CGFloat/NSArray(NSTextTab)</td> </tr>
下面是效果圖

示例圖

示例圖

示例圖
五、YYText用法
1. 基本用法
// YYLabel (和 UILabel 用法一致) YYLabel *label = [YYLabel new]; label.frame = ... label.font = ... label.textColor = ... label.textAlignment = ... label.lineBreakMode = ... label.numberOfLines = ... label.text = ... // YYTextView (和 UITextView 用法一致) YYTextView *textView = [YYTextView new]; textView.frame = ... textView.font = ... textView.textColor = ... textView.dataDetectorTypes = ... textView.placeHolderText = ... textView.placeHolderTextColor = ... textView.delegate = ...
2. 屬性文字
// 1. 建立一個屬性文字 NSMutableAttributedString *text = [[NSMutableAttributedString alloc] 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;
3. 文字高亮
你可以用一些已經封裝好的簡便方法來設定文字高亮:
[text yy_setTextHighlightRange:range color:[UIColor blueColor] backgroundColor:[UIColor grayColor] tapAction:^(UIView *containerView, NSAttributedString *text, NSRange range, CGRect rect){ 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, NSRange range, 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:..."); }
4. 圖文混排
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:UIViewContentModeBottom attachmentSize: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];
5. 文字佈局計算
NSAttributedString *text = ... CGSize size = 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;
6. 文字行位置調整
// 由於中文、英文、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;
7. 非同步排版和渲染
// 如果你在顯示字串時有效能問題,可以這樣開啟非同步模式: 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; }); });
8. 文字容器控制
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;
9. 文字解析
// 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]; [parser setColorWithDarkTheme]; // 實現 `YYTextParser` 協議的自定義解析器 MyCustomParser *parser = ... // 2. 把解析器新增到 YYLabel 或 YYTextView YYLabel *label = ... label.textParser = parser; YYTextView *textView = ... textView.textParser = parser;
10. Debug
// 設定一個全域性的 debug option 來顯示排版結果。 YYTextDebugOption *debugOptions = [YYTextDebugOption new]; debugOptions.baselineColor = [UIColor redColor]; debugOptions.CTFrameBorderColor = [UIColor redColor]; debugOptions.CTLineFillColor = [UIColor colorWithRed:0.000 green:0.463 blue:1.000 alpha:0.180]; debugOptions.CGGlyphBorderColor = [UIColor colorWithRed:1.000 green:0.524 blue:0.000 alpha:0.200]; [YYTextDebugOption setSharedDebugOption:debugOptions];
六、YYText安裝
1. CocoaPods
1. 在 Podfile 中新增 pod 'YYText'。 2. 執行 pod install 或 pod update。 3. 匯入 <YYText/YYText.h>。
2. Carthage
1. 在 Cartfile 中新增 github "ibireme/YYText"。 2. 執行 carthage update --platform ios 並將生成的 framework 新增到你的工程。 3. 匯入 <YYText/YYText.h>。
3. 手動安裝
1. 下載 YYText 資料夾內的所有內容。 2. 將 YYText 內的原始檔新增(拖放)到你的工程。 3. 連結以下 frameworks: - UIKit - CoreFoundation - CoreText - QuartzCore - Accelerate - MobileCoreServices 4. 匯入 YYText.h。
注意
你可以新增 YYImage 或 YYWebImage 到你的工程,以支援動畫格式(GIF/APNG/WebP)的圖片。
七、系統要求
該專案最低支援 iOS 6.0 和 Xcode 7.0。
八、已知問題
- YYText 並不能支援所有 CoreText/TextKit 的屬性,比如 NSBackgroundColor、NSStrikethrough、NSUnderline、NSAttachment、NSLink 等,但 YYText 中基本都有對應屬性作為替代。詳情見上方表格。
- YYTextView 未實現區域性重新整理,所以在輸入和編輯大量的文字(比如超過大概五千個漢字、或大概一萬個英文字元)時會出現較明顯的卡頓現象。
- 豎排版時,新增 exclusionPaths 在少數情況下可能會導致文字顯示空白。
- 當添加了非矩形的 textContainerPath,並且有嵌入大於文字排版方向寬度的 RunDelegate 時,RunDelegate 之後的文字會無法顯示。這是 CoreText 的 Bug(或者說是 Feature)。
後記
未完,待續,後續會完善~~~~

奮鬥