{"id":2008,"url":"https://github.com/ibireme/YYText","last_synced_at":"2025-08-02T23:31:34.642Z","repository":{"id":40531834,"uuid":"45612129","full_name":"ibireme/YYText","owner":"ibireme","description":"Powerful text framework for iOS to display and edit rich text.","archived":false,"fork":false,"pushed_at":"2024-07-16T06:32:03.000Z","size":21807,"stargazers_count":8867,"open_issues_count":510,"forks_count":1702,"subscribers_count":206,"default_branch":"master","last_synced_at":"2024-12-02T15:07:45.775Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Objective-C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ibireme.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-11-05T13:13:53.000Z","updated_at":"2024-11-28T16:50:01.000Z","dependencies_parsed_at":"2024-10-29T10:37:38.801Z","dependency_job_id":null,"html_url":"https://github.com/ibireme/YYText","commit_stats":{"total_commits":157,"total_committers":11,"mean_commits":"14.272727272727273","dds":0.08917197452229297,"last_synced_commit":"7bd2aa41414736f6451241725778509fe75860b5"},"previous_names":[],"tags_count":28,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ibireme%2FYYText","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ibireme%2FYYText/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ibireme%2FYYText/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ibireme%2FYYText/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ibireme","download_url":"https://codeload.github.com/ibireme/YYText/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":228503092,"owners_count":17930509,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-01-05T20:16:01.103Z","updated_at":"2024-12-06T17:30:33.159Z","avatar_url":"https://github.com/ibireme.png","language":"Objective-C","funding_links":[],"categories":["awesome-ios ##","Objective-C","Objective-C  Stars 1000以内排名整理","UI","Text","iOS"],"sub_categories":["Layout","Other free courses","Other Testing","Keychain","YYKit"],"readme":"YYText\n==============\n[![License MIT](https://img.shields.io/badge/license-MIT-green.svg?style=flat)](https://raw.githubusercontent.com/ibireme/YYText/master/LICENSE)\u0026nbsp;\n[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)\u0026nbsp;\n[![CocoaPods](http://img.shields.io/cocoapods/v/YYText.svg?style=flat)](http://cocoapods.org/pods/YYText)\u0026nbsp;\n[![CocoaPods](http://img.shields.io/cocoapods/p/YYText.svg?style=flat)](http://cocoadocs.org/docsets/YYText)\u0026nbsp;\n[![Support](https://img.shields.io/badge/support-iOS%206%2B%20-blue.svg?style=flat)](https://www.apple.com/nl/ios/)\u0026nbsp;\n[![Build Status](https://travis-ci.org/ibireme/YYText.svg?branch=master)](https://travis-ci.org/ibireme/YYText)\n\nPowerful text framework for iOS to display and edit rich text.\u003cbr/\u003e\n(It's a component of [YYKit](https://github.com/ibireme/YYKit))\n\n\nFeatures\n==============\n\n- UILabel and UITextView API compatible\n- High performance asynchronous text layout and rendering\n- Extended CoreText attributes with more text effects\n- Text attachments with UIImage, UIView and CALayer\n- Custom highlight text range to allow user interact with\n- Text parser support (built in markdown/emoticon parser)\n- Text container path and exclusion paths support\n- Vertical form layout support (for CJK text)\n- Image and attributed text copy/paste support\n- Attributed text placeholder support\n- Custom keyboard view support\n- Undo and redo control\n- Attributed text archiver and unarchiver support\n- Multi-language and VoiceOver support\n- Interface Builder support\n- Fully documented\n\n\nArchitecture\n==============\nYYText vs TextKit\n\n\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/architecture.png\" width=\"400\"\u003e\n\n\nText Attributes\n==============\n\n### YYText supported attributes\n\u003ctable\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n      \u003cth\u003eDemo\u003c/th\u003e\n      \u003cth\u003eAttribute Name\u003c/th\u003e\n      \u003cth\u003eClass\u003c/th\u003e\n    \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/YYText Extended/YYTextAttachment.gif\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003eTextAttachment\u003c/td\u003e\n      \u003ctd\u003eYYTextAttachment\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/YYText Extended/YYTextHighlight.gif\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003eTextHighlight\u003c/td\u003e\n      \u003ctd\u003eYYTextHighlight\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/YYText Extended/YYTextBinding.gif\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003eTextBinding\u003c/td\u003e\n      \u003ctd\u003eYYTextBinding\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/YYText Extended/YYTextShadow.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003eTextShadow\u003cbr/\u003eTextInnerShadow\u003c/td\u003e\n      \u003ctd\u003eYYTextShadow\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/YYText Extended/YYTextBorder.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003eTextBorder\u003c/td\u003e\n      \u003ctd\u003eYYTextBorder\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/YYText Extended/YYTextBackgroundBorder.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003eTextBackgroundBorder\u003c/td\u003e\n      \u003ctd\u003eYYTextBorder\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/YYText Extended/YYTextBlockBorder.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003eTextBlockBorder\u003c/td\u003e\n      \u003ctd\u003eYYTextBorder\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/CoreText and TextKit/Obliqueness.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003eTextGlyphTransform\u003c/td\u003e\n      \u003ctd\u003e NSValue(CGAffineTransform)\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/CoreText and TextKit/Underline.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003eTextUnderline\u003c/td\u003e\n      \u003ctd\u003eYYTextDecoration\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/CoreText and TextKit/Strikethrough.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003eTextStrickthrough\u003c/td\u003e\n      \u003ctd\u003eYYTextDecoration\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/YYText Extended/YYTextBackedString.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003eTextBackedString\u003c/td\u003e\n      \u003ctd\u003eYYTextBackedString\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n### CoreText attributes which is supported by YYText\n\u003ctable\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n      \u003cth\u003eDemo\u003c/th\u003e\n      \u003cth\u003eAttribute Name\u003c/th\u003e\n      \u003cth\u003eClass\u003c/th\u003e\n    \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/CoreText and TextKit/Font.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003e Font \u003c/td\u003e\n      \u003ctd\u003eUIFont(CTFontRef)\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/CoreText and TextKit/Kern.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003e Kern \u003c/td\u003e\n      \u003ctd\u003eNSNumber\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/CoreText and TextKit/Stroke.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003e StrokeWidth \u003c/td\u003e\n      \u003ctd\u003e NSNumber \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/CoreText and TextKit/StrokeColor.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003e StrokeColor \u003c/td\u003e\n      \u003ctd\u003e CGColorRef \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/CoreText and TextKit/Shadow.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003e Shadow \u003c/td\u003e\n      \u003ctd\u003e NSShadow \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/CoreText and TextKit/Ligature.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003e Ligature \u003c/td\u003e\n      \u003ctd\u003e NSNumber \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/CoreText and TextKit/VerticalForms.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003e VerticalGlyphForm \u003c/td\u003e\n      \u003ctd\u003e NSNumber(BOOL) \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/CoreText and TextKit/WriteDirection.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003e WritingDirection \u003c/td\u003e\n      \u003ctd\u003e NSArray(NSNumber) \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/CoreText and TextKit/RunDelegate.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003e RunDelegate \u003c/td\u003e\n      \u003ctd\u003e CTRunDelegateRef \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/CoreText and TextKit/Paragraph/Alignment.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003e TextAlignment \u003c/td\u003e\n      \u003ctd\u003e NSParagraphStyle \u003cbr/\u003e(NSTextAlignment) \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/CoreText and TextKit/Paragraph/LineBreakMode.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003e LineBreakMode \u003c/td\u003e\n      \u003ctd\u003e NSParagraphStyle \u003cbr/\u003e(NSLineBreakMode) \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/CoreText and TextKit/Paragraph/LineSpacing.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003e LineSpacing \u003c/td\u003e\n      \u003ctd\u003e NSParagraphStyle \u003cbr/\u003e(CGFloat) \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/CoreText and TextKit/Paragraph/ParagraphSpacing.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003e ParagraphSpacing \u003cbr/\u003e ParagraphSpacingBefore \u003c/td\u003e\n      \u003ctd\u003e NSParagraphStyle \u003cbr/\u003e(CGFloat) \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/CoreText and TextKit/Paragraph/FirstLineHeadIndent.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003e FirstLineHeadIndent \u003c/td\u003e\n      \u003ctd\u003e NSParagraphStyle \u003cbr/\u003e(CGFloat) \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/CoreText and TextKit/Paragraph/HeadIndent.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003e HeadIndent \u003c/td\u003e\n      \u003ctd\u003e NSParagraphStyle \u003cbr/\u003e(CGFloat) \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/CoreText and TextKit/Paragraph/TailIndent.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003e TailIndent \u003c/td\u003e\n      \u003ctd\u003e NSParagraphStyle \u003cbr/\u003e(CGFloat) \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/CoreText and TextKit/Paragraph/MinimumLineHeight.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003e MinimumLineHeight \u003c/td\u003e\n      \u003ctd\u003e NSParagraphStyle \u003cbr/\u003e(CGFloat) \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/CoreText and TextKit/Paragraph/MaximumLineHeight.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003e MaximumLineHeight \u003c/td\u003e\n      \u003ctd\u003e NSParagraphStyle \u003cbr/\u003e(CGFloat) \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/CoreText and TextKit/Paragraph/LineHeightMultiple.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003e LineHeightMultiple \u003c/td\u003e\n      \u003ctd\u003e NSParagraphStyle \u003cbr/\u003e(CGFloat) \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/CoreText and TextKit/Paragraph/BaseWritingDirection.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003e BaseWritingDirection \u003c/td\u003e\n      \u003ctd\u003e NSParagraphStyle \u003cbr/\u003e(NSWritingDirection) \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/CoreText and TextKit/Paragraph/Tab.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003e DefaultTabInterval \u003cbr/\u003e TabStops \u003c/td\u003e\n      \u003ctd\u003e NSParagraphStyle \u003cbr/\u003eCGFloat/NSArray(NSTextTab)\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n\nUsage\n==============\n\n### Basic\n```objc\n// YYLabel (similar to UILabel)\nYYLabel *label = [YYLabel new];\nlabel.frame = ...\nlabel.font = ...\nlabel.textColor = ...\nlabel.textAlignment = ...\nlabel.lineBreakMode = ...\nlabel.numberOfLines = ...\nlabel.text = ...\n    \n// YYTextView (similar to UITextView)\nYYTextView *textView = [YYTextView new];\ntextView.frame = ...\ntextView.font = ...\ntextView.textColor = ...\ntextView.dataDetectorTypes = ...\ntextView.placeHolderText = ...\ntextView.placeHolderTextColor = ...\ntextView.delegate = ...\n```    \n\n### Attributed text\n```objc\n// 1. Create an attributed string.\nNSMutableAttributedString *text = [[NSMutableAttributedString alloc] initWithString:@\"Some Text, blabla...\"];\n    \n// 2. Set attributes to text, you can use almost all CoreText attributes.\ntext.yy_font = [UIFont boldSystemFontOfSize:30];\ntext.yy_color = [UIColor blueColor];\n[text yy_setColor:[UIColor redColor] range:NSMakeRange(0, 4)];\ntext.yy_lineSpacing = 10;\n    \n// 3. Set to YYLabel or YYTextView.\nYYLabel *label = [YYLabel new];\nlabel.frame = ...\nlabel.attributedString = text;\n    \nYYTextView *textView = [YYTextView new];\ntextView.frame = ...\ntextView.attributedString = text;\n```\n\n### Text highlight\n    \nYou can use some convenience methods to set text highlight:\n```objc\n[text yy_setTextHighlightRange:range\n                       color:[UIColor blueColor]\n             backgroundColor:[UIColor grayColor]\n                   tapAction:^(UIView *containerView, NSAttributedString *text, NSRange range, CGRect rect){ \n                       NSLog(@\"tap text range:...\"); \n                   }];\n```\nOr set the text highlight with your custom config:\n```objc\n// 1. Create a 'highlight' attribute for text.\nYYTextBorder *border = [YYTextBorder borderWithFillColor:[UIColor grayColor] cornerRadius:3];\n   \nYYTextHighlight *highlight = [YYTextHighlight new];\n[highlight setColor:[UIColor whiteColor]];\n[highlight setBackgroundBorder:highlightBorder];\nhighlight.tapAction = ^(UIView *containerView, NSAttributedString *text, NSRange range, CGRect rect) {\n NSLog(@\"tap text range:...\"); \n // you can also set the action handler to YYLabel or YYTextView.\n};\n    \n// 2. Add 'highlight' attribute to a range of text.\n[attributedText yy_setTextHighlight:highlight range:highlightRange];\n    \n// 3. Set text to label or text view.\nYYLabel *label = ...\nlabel.attributedText = attributedText\n    \nYYTextView *textView = ...\ntextView.attributedText = ...\n    \n// 4. Receive user interactive action.\nlabel.highlightTapAction = ^(UIView *containerView, NSAttributedString *text, NSRange range, CGRect rect) {\n   NSLog(@\"tap text range:...\");\n};\nlabel.highlightLongPressAction = ^(UIView *containerView, NSAttributedString *text, NSRange range, CGRect rect) {\n   NSLog(@\"long press text range:...\");\n};\n    \n@UITextViewDelegate\n- (void)textView:(YYTextView *)textView didTapHighlight:(YYTextHighlight *)highlight inRange:(NSRange)characterRange rect:(CGRect)rect {\n   NSLog(@\"tap text range:...\");\n}\n- (void)textView:(YYTextView *)textView didLongPressHighlight:(YYTextHighlight *)highlight inRange:(NSRange)characterRange rect:(CGRect)rect {\n   NSLog(@\"long press text range:...\");\n}\n```\n\n### Text attachments\n```objc\nNSMutableAttributedString *text = [NSMutableAttributedString new];\nUIFont *font = [UIFont systemFontOfSize:16];\nNSMutableAttributedString *attachment = nil;\n\t\n// UIImage attachment\nUIImage *image = [UIImage imageNamed:@\"dribbble64_imageio\"];\nattachment = [NSMutableAttributedString yy_attachmentStringWithContent:image contentMode:UIViewContentModeCenter attachmentSize:image.size alignToFont:font alignment:YYTextVerticalAlignmentCenter];\n[text appendAttributedString: attachment];\n\t\n// UIView attachment\nUISwitch *switcher = [UISwitch new];\n[switcher sizeToFit];\nattachment = [NSMutableAttributedString yy_attachmentStringWithContent:switcher contentMode:UIViewContentModeBottom attachmentSize:switcher.size alignToFont:font alignment:YYTextVerticalAlignmentCenter];\n[text appendAttributedString: attachment];\n\t\n// CALayer attachment\nCASharpLayer *layer = [CASharpLayer layer];\nlayer.path = ...\nattachment = [NSMutableAttributedString yy_attachmentStringWithContent:layer contentMode:UIViewContentModeBottom attachmentSize:switcher.size alignToFont:font alignment:YYTextVerticalAlignmentCenter];\n[text appendAttributedString: attachment];\n```\n\n### Text layout calculation\n```objc\nNSAttributedString *text = ...\nCGSize size = CGSizeMake(100, CGFLOAT_MAX);\nYYTextLayout *layout = [YYTextLayout layoutWithContainerSize:size text:text];\n\t\n// get text bounding\nlayout.textBoundingRect; // get bounding rect\nlayout.textBoundingSize; // get bounding size\n\t\n // query text layout\n[layout lineIndexForPoint:CGPointMake(10,10)];\n[layout closestLineIndexForPoint:CGPointMake(10,10)];\n[layout closestPositionToPoint:CGPointMake(10,10)];\n[layout textRangeAtPoint:CGPointMake(10,10)];\n[layout rectForRange:[YYTextRange rangeWithRange:NSMakeRange(10,2)]];\n[layout selectionRectsForRange:[YYTextRange rangeWithRange:NSMakeRange(10,2)]];\n\t\n// text layout display\nYYLabel *label = [YYLabel new];\nlabel.size = layout.textBoundingSize;\nlabel.textLayout = layout;\n```\n\n### Adjust text line position\n```objc\n// Convenience methods:\n// 1. Create a text line position modifier, implements `YYTextLinePositionModifier` protocol.\n// 2. Set it to label or text view.\n\t\nYYTextLinePositionSimpleModifier *modifier = [YYTextLinePositionSimpleModifier new];\nmodifier.fixedLineHeight = 24;\n\t\nYYLabel *label = [YYLabel new];\nlabel.linePositionModifier = modifier;\n\t\n// Fully control\nYYTextLinePositionSimpleModifier *modifier = [YYTextLinePositionSimpleModifier new];\nmodifier.fixedLineHeight = 24;\n\t\nYYTextContainer *container = [YYTextContainer new];\ncontainer.size = CGSizeMake(100, CGFLOAT_MAX);\ncontainer.linePositionModifier = modifier;\n\t\nYYTextLayout *layout = [YYTextLayout layoutWithContainer:container text:text];\nYYLabel *label = [YYLabel new];\nlabel.size = layout.textBoundingSize;\nlabel.textLayout = layout;\n```\t\n\t\n### Asynchronous layout and rendering\n```objc\n// If you have performance issues,\n// you may enable the asynchronous display mode.\nYYLabel *label = ...\nlabel.displaysAsynchronously = YES;\n    \n// If you want to get the highest performance, you should do \n// text layout with `YYTextLayout` class in background thread.\nYYLabel *label = [YYLabel new];\nlabel.displaysAsynchronously = YES;\nlabel.ignoreCommonProperties = YES;\n    \ndispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{\n   // Create attributed string.\n   NSMutableAttributedString *text = [[NSMutableAttributedString alloc] initWithString:@\"Some Text\"];\n   text.yy_font = [UIFont systemFontOfSize:16];\n   text.yy_color = [UIColor grayColor];\n   [text yy_setColor:[UIColor redColor] range:NSMakeRange(0, 4)];\n \t\n   // Create text container\n   YYTextContainer *container = [YYTextContainer new];\n   container.size = CGSizeMake(100, CGFLOAT_MAX);\n   container.maximumNumberOfRows = 0;\n   \n   // Generate a text layout.\n   YYTextLayout *layout = [YYTextLayout layoutWithContainer:container text:text];\n   \n   dispatch_async(dispatch_get_main_queue(), ^{\n       label.size = layout.textBoundingSize;\n       label.textLayout = layout;\n   });\n});\n```\n\n### Text container control\n```objc\nYYLabel *label = ...\nlabel.textContainerPath = [UIBezierPath bezierPathWith...];\nlabel.exclusionPaths = \t@[[UIBezierPath bezierPathWith...];,...];\nlabel.textContainerInset = UIEdgeInsetsMake(...);\nlabel.verticalForm = YES/NO;\n    \nYYTextView *textView = ...\ntextView.exclusionPaths = \t@[[UIBezierPath bezierPathWith...];,...];\ntextView.textContainerInset = UIEdgeInsetsMake(...);\ntextView.verticalForm = YES/NO;\n```\n   \n### Text parser\n```objc\n// 1. Create a text parser\n\t\nYYTextSimpleEmoticonParser *parser = [YYTextSimpleEmoticonParser new];\nNSMutableDictionary *mapper = [NSMutableDictionary new];\nmapper[@\":smile:\"] = [UIImage imageNamed:@\"smile.png\"];\nmapper[@\":cool:\"] = [UIImage imageNamed:@\"cool.png\"];\nmapper[@\":cry:\"] = [UIImage imageNamed:@\"cry.png\"];\nmapper[@\":wink:\"] = [UIImage imageNamed:@\"wink.png\"];\nparser.emoticonMapper = mapper;\n\t\nYYTextSimpleMarkdownParser *parser = [YYTextSimpleMarkdownParser new];\n[parser setColorWithDarkTheme];\n    \nMyCustomParser *parser = ... // custom parser\n    \n// 2. Attach parser to label or text view\nYYLabel *label = ...\nlabel.textParser = parser;\n    \nYYTextView *textView = ...\ntextView.textParser = parser;\n```\n  \n### Debug\n```objc\n// Set a shared debug option to show text layout result.\nYYTextDebugOption *debugOptions = [YYTextDebugOption new];\ndebugOptions.baselineColor = [UIColor redColor];\ndebugOptions.CTFrameBorderColor = [UIColor redColor];\ndebugOptions.CTLineFillColor = [UIColor colorWithRed:0.000 green:0.463 blue:1.000 alpha:0.180];\ndebugOptions.CGGlyphBorderColor = [UIColor colorWithRed:1.000 green:0.524 blue:0.000 alpha:0.200];\n[YYTextDebugOption setSharedDebugOption:debugOptions];\n```\n\n### More examples\nSee `Demo/YYTextDemo.xcodeproj` for more examples:\n\n\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Demo/DemoSnapshot/text_path.gif\" width=\"320\"\u003e\n\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Demo/DemoSnapshot/text_markdown.gif\" width=\"320\"\u003e\n\u003cbr/\u003e \u003cbr/\u003e\n\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Demo/DemoSnapshot/text_vertical.gif\" width=\"320\"\u003e\n\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Demo/DemoSnapshot/text_paste.gif\" width=\"320\"\u003e\n\n\nInstallation\n==============\n\n### CocoaPods\n\n1. Add `pod 'YYText'` to your Podfile.\n2. Run `pod install` or `pod update`.\n3. Import \\\u003cYYText/YYText.h\\\u003e.\n\n\n### Carthage\n\n1. Add `github \"ibireme/YYText\"` to your Cartfile.\n2. Run `carthage update --platform ios` and add the framework to your project.\n3. Import \\\u003cYYText/YYText.h\\\u003e.\n\n\n### Manually\n\n1. Download all the files in the `YYText` subdirectory.\n2. Add the source files to your Xcode project.\n3. Link with required frameworks:\n    * UIKit\n    * CoreFoundation\n    * CoreText\n    * QuartzCore\n    * Accelerate\n    * MobileCoreServices\n4. Import `YYText.h`.\n\n\n### Notice\nYou may add [YYImage](https://github.com/ibireme/YYImage) or [YYWebImage](https://github.com/ibireme/YYWebImage) to your project if you want to support animated image (GIF/APNG/WebP).\n\n\nDocumentation\n==============\nFull API documentation is available on [CocoaDocs](http://cocoadocs.org/docsets/YYText/).\u003cbr/\u003e\nYou can also install documentation locally using [appledoc](https://github.com/tomaz/appledoc).\n\n\nRequirements\n==============\nThis library requires `iOS 6.0+` and `Xcode 8.0+`.\n\n\nLicense\n==============\nYYText is released under the MIT license. See LICENSE file for details.\n\n\n\u003cbr/\u003e\u003cbr/\u003e\n---\n中文介绍\n==============\n功能强大的 iOS 富文本编辑与显示框架。\u003cbr/\u003e\n(该项目是 [YYKit](https://github.com/ibireme/YYKit) 组件之一)\n\n\n特性\n==============\n- API 兼容 UILabel 和 UITextView\n- 支持高性能的异步排版和渲染\n- 扩展了 CoreText 的属性以支持更多文字效果\n- 支持 UIImage、UIView、CALayer 作为图文混排元素\n- 支持添加自定义样式的、可点击的文本高亮范围\n- 支持自定义文本解析 (内置简单的 Markdown/表情解析)\n- 支持文本容器路径、内部留空路径的控制\n- 支持文字竖排版，可用于编辑和显示中日韩文本\n- 支持图片和富文本的复制粘贴\n- 文本编辑时，支持富文本占位符\n- 支持自定义键盘视图\n- 撤销和重做次数的控制\n- 富文本的序列化与反序列化支持\n- 支持多语言，支持 VoiceOver\n- 支持 Interface Builder\n- 全部代码都有文档注释\n\n\n架构\n==============\nYYText 和 TextKit 架构对比\n\n\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/architecture.png\" width=\"400\"\u003e\n\n\n文本属性\n==============\n\n### YYText 原生支持的属性\n\u003ctable\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n      \u003cth\u003eDemo\u003c/th\u003e\n      \u003cth\u003eAttribute Name\u003c/th\u003e\n      \u003cth\u003eClass\u003c/th\u003e\n    \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/YYText Extended/YYTextAttachment.gif\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003eTextAttachment\u003c/td\u003e\n      \u003ctd\u003eYYTextAttachment\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/YYText Extended/YYTextHighlight.gif\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003eTextHighlight\u003c/td\u003e\n      \u003ctd\u003eYYTextHighlight\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/YYText Extended/YYTextBinding.gif\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003eTextBinding\u003c/td\u003e\n      \u003ctd\u003eYYTextBinding\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/YYText Extended/YYTextShadow.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003eTextShadow\u003cbr/\u003eTextInnerShadow\u003c/td\u003e\n      \u003ctd\u003eYYTextShadow\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/YYText Extended/YYTextBorder.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003eTextBorder\u003c/td\u003e\n      \u003ctd\u003eYYTextBorder\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/YYText Extended/YYTextBackgroundBorder.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003eTextBackgroundBorder\u003c/td\u003e\n      \u003ctd\u003eYYTextBorder\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/YYText Extended/YYTextBlockBorder.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003eTextBlockBorder\u003c/td\u003e\n      \u003ctd\u003eYYTextBorder\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/CoreText and TextKit/Obliqueness.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003eTextGlyphTransform\u003c/td\u003e\n      \u003ctd\u003e NSValue(CGAffineTransform)\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/CoreText and TextKit/Underline.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003eTextUnderline\u003c/td\u003e\n      \u003ctd\u003eYYTextDecoration\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/CoreText and TextKit/Strikethrough.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003eTextStrickthrough\u003c/td\u003e\n      \u003ctd\u003eYYTextDecoration\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/YYText Extended/YYTextBackedString.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003eTextBackedString\u003c/td\u003e\n      \u003ctd\u003eYYTextBackedString\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n### YYText 支持的 CoreText 属性\n\u003ctable\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n      \u003cth\u003eDemo\u003c/th\u003e\n      \u003cth\u003eAttribute Name\u003c/th\u003e\n      \u003cth\u003eClass\u003c/th\u003e\n    \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/CoreText and TextKit/Font.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003e Font \u003c/td\u003e\n      \u003ctd\u003eUIFont(CTFontRef)\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/CoreText and TextKit/Kern.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003e Kern \u003c/td\u003e\n      \u003ctd\u003eNSNumber\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/CoreText and TextKit/Stroke.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003e StrokeWidth \u003c/td\u003e\n      \u003ctd\u003e NSNumber \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/CoreText and TextKit/StrokeColor.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003e StrokeColor \u003c/td\u003e\n      \u003ctd\u003e CGColorRef \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/CoreText and TextKit/Shadow.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003e Shadow \u003c/td\u003e\n      \u003ctd\u003e NSShadow \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/CoreText and TextKit/Ligature.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003e Ligature \u003c/td\u003e\n      \u003ctd\u003e NSNumber \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/CoreText and TextKit/VerticalForms.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003e VerticalGlyphForm \u003c/td\u003e\n      \u003ctd\u003e NSNumber(BOOL) \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/CoreText and TextKit/WriteDirection.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003e WritingDirection \u003c/td\u003e\n      \u003ctd\u003e NSArray(NSNumber) \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/CoreText and TextKit/RunDelegate.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003e RunDelegate \u003c/td\u003e\n      \u003ctd\u003e CTRunDelegateRef \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/CoreText and TextKit/Paragraph/Alignment.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003e TextAlignment \u003c/td\u003e\n      \u003ctd\u003e NSParagraphStyle \u003cbr/\u003e(NSTextAlignment) \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/CoreText and TextKit/Paragraph/LineBreakMode.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003e LineBreakMode \u003c/td\u003e\n      \u003ctd\u003e NSParagraphStyle \u003cbr/\u003e(NSLineBreakMode) \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/CoreText and TextKit/Paragraph/LineSpacing.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003e LineSpacing \u003c/td\u003e\n      \u003ctd\u003e NSParagraphStyle \u003cbr/\u003e(CGFloat) \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/CoreText and TextKit/Paragraph/ParagraphSpacing.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003e ParagraphSpacing \u003cbr/\u003e ParagraphSpacingBefore \u003c/td\u003e\n      \u003ctd\u003e NSParagraphStyle \u003cbr/\u003e(CGFloat) \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/CoreText and TextKit/Paragraph/FirstLineHeadIndent.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003e FirstLineHeadIndent \u003c/td\u003e\n      \u003ctd\u003e NSParagraphStyle \u003cbr/\u003e(CGFloat) \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/CoreText and TextKit/Paragraph/HeadIndent.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003e HeadIndent \u003c/td\u003e\n      \u003ctd\u003e NSParagraphStyle \u003cbr/\u003e(CGFloat) \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/CoreText and TextKit/Paragraph/TailIndent.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003e TailIndent \u003c/td\u003e\n      \u003ctd\u003e NSParagraphStyle \u003cbr/\u003e(CGFloat) \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/CoreText and TextKit/Paragraph/MinimumLineHeight.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003e MinimumLineHeight \u003c/td\u003e\n      \u003ctd\u003e NSParagraphStyle \u003cbr/\u003e(CGFloat) \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/CoreText and TextKit/Paragraph/MaximumLineHeight.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003e MaximumLineHeight \u003c/td\u003e\n      \u003ctd\u003e NSParagraphStyle \u003cbr/\u003e(CGFloat) \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/CoreText and TextKit/Paragraph/LineHeightMultiple.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003e LineHeightMultiple \u003c/td\u003e\n      \u003ctd\u003e NSParagraphStyle \u003cbr/\u003e(CGFloat) \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/CoreText and TextKit/Paragraph/BaseWritingDirection.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003e BaseWritingDirection \u003c/td\u003e\n      \u003ctd\u003e NSParagraphStyle \u003cbr/\u003e(NSWritingDirection) \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Attributes/CoreText and TextKit/Paragraph/Tab.png\" width=\"200\"\u003e\u003c/td\u003e\n      \u003ctd\u003e DefaultTabInterval \u003cbr/\u003e TabStops \u003c/td\u003e\n      \u003ctd\u003e NSParagraphStyle \u003cbr/\u003eCGFloat/NSArray(NSTextTab)\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n\n用法\n==============\n\n### 基本用法\n```objc\n// YYLabel (和 UILabel 用法一致)\nYYLabel *label = [YYLabel new];\nlabel.frame = ...\nlabel.font = ...\nlabel.textColor = ...\nlabel.textAlignment = ...\nlabel.lineBreakMode = ...\nlabel.numberOfLines = ...\nlabel.text = ...\n    \n// YYTextView (和 UITextView 用法一致)\nYYTextView *textView = [YYTextView new];\ntextView.frame = ...\ntextView.font = ...\ntextView.textColor = ...\ntextView.dataDetectorTypes = ...\ntextView.placeHolderText = ...\ntextView.placeHolderTextColor = ...\ntextView.delegate = ...\n```    \n\n### 属性文本\n```objc\n// 1. 创建一个属性文本\nNSMutableAttributedString *text = [[NSMutableAttributedString alloc] initWithString:@\"Some Text, blabla...\"];\n    \n// 2. 为文本设置属性\ntext.yy_font = [UIFont boldSystemFontOfSize:30];\ntext.yy_color = [UIColor blueColor];\n[text yy_setColor:[UIColor redColor] range:NSMakeRange(0, 4)];\ntext.yy_lineSpacing = 10;\n    \n// 3. 赋值到 YYLabel 或 YYTextView\nYYLabel *label = [YYLabel new];\nlabel.frame = ...\nlabel.attributedString = text;\n    \nYYTextView *textView = [YYTextView new];\ntextView.frame = ...\ntextView.attributedString = text;\n```   \n\n### 文本高亮\n\n你可以用一些已经封装好的简便方法来设置文本高亮：\n```objc\n[text yy_setTextHighlightRange:range\n                       color:[UIColor blueColor]\n             backgroundColor:[UIColor grayColor]\n                   tapAction:^(UIView *containerView, NSAttributedString *text, NSRange range, CGRect rect){ \n                       NSLog(@\"tap text range:...\"); \n                   }];\n```\n或者用更复杂的办法来调节文本高亮的细节：\n```objc\n// 1. 创建一个\"高亮\"属性，当用户点击了高亮区域的文本时，\"高亮\"属性会替换掉原本的属性\nYYTextBorder *border = [YYTextBorder borderWithFillColor:[UIColor grayColor] cornerRadius:3];\n   \nYYTextHighlight *highlight = [YYTextHighlight new];\n[highlight setColor:[UIColor whiteColor]];\n[highlight setBackgroundBorder:highlightBorder];\nhighlight.tapAction = ^(UIView *containerView, NSAttributedString *text, NSRange range, CGRect rect) {\n NSLog(@\"tap text range:...\"); \n // 你也可以把事件回调放到 YYLabel 和 YYTextView 来处理。\n};\n    \n// 2. 把\"高亮\"属性设置到某个文本范围\n[attributedText yy_setTextHighlight:highlight range:highlightRange];\n    \n// 3. 把属性文本设置到 YYLabel 或 YYTextView\nYYLabel *label = ...\nlabel.attributedText = attributedText\n    \nYYTextView *textView = ...\ntextView.attributedText = ...\n    \n// 4. 接受事件回调\nlabel.highlightTapAction = ^(UIView *containerView, NSAttributedString *text, NSRange range, CGRect rect) {\n   NSLog(@\"tap text range:...\");\n};\nlabel.highlightLongPressAction = ^(UIView *containerView, NSAttributedString *text, NSRange range, CGRect rect) {\n   NSLog(@\"long press text range:...\");\n};\n    \n@UITextViewDelegate\n- (void)textView:(YYTextView *)textView didTapHighlight:(YYTextHighlight *)highlight inRange:(NSRange)characterRange rect:(CGRect)rect {\n   NSLog(@\"tap text range:...\");\n}\n- (void)textView:(YYTextView *)textView didLongPressHighlight:(YYTextHighlight *)highlight inRange:(NSRange)characterRange rect:(CGRect)rect {\n   NSLog(@\"long press text range:...\");\n}\n```\n\n### 图文混排\n```objc\nNSMutableAttributedString *text = [NSMutableAttributedString new];\nUIFont *font = [UIFont systemFontOfSize:16];\nNSMutableAttributedString *attachment = nil;\n\t\n// 嵌入 UIImage\nUIImage *image = [UIImage imageNamed:@\"dribbble64_imageio\"];\nattachment = [NSMutableAttributedString yy_attachmentStringWithContent:image contentMode:UIViewContentModeCenter attachmentSize:image.size alignToFont:font alignment:YYTextVerticalAlignmentCenter];\n[text appendAttributedString: attachment];\n\t\n// 嵌入 UIView\nUISwitch *switcher = [UISwitch new];\n[switcher sizeToFit];\nattachment = [NSMutableAttributedString yy_attachmentStringWithContent:switcher contentMode:UIViewContentModeBottom attachmentSize:switcher.size alignToFont:font alignment:YYTextVerticalAlignmentCenter];\n[text appendAttributedString: attachment];\n\t\n// 嵌入 CALayer\nCASharpLayer *layer = [CASharpLayer layer];\nlayer.path = ...\nattachment = [NSMutableAttributedString yy_attachmentStringWithContent:layer contentMode:UIViewContentModeBottom attachmentSize:switcher.size alignToFont:font alignment:YYTextVerticalAlignmentCenter];\n[text appendAttributedString: attachment];\n```\n\n### 文本布局计算\n```objc\nNSAttributedString *text = ...\nCGSize size = CGSizeMake(100, CGFLOAT_MAX);\nYYTextLayout *layout = [YYTextLayout layoutWithContainerSize:size text:text];\n\t\n// 获取文本显示位置和大小\nlayout.textBoundingRect; // get bounding rect\nlayout.textBoundingSize; // get bounding size\n\t\n // 查询文本排版结果\n[layout lineIndexForPoint:CGPointMake(10,10)];\n[layout closestLineIndexForPoint:CGPointMake(10,10)];\n[layout closestPositionToPoint:CGPointMake(10,10)];\n[layout textRangeAtPoint:CGPointMake(10,10)];\n[layout rectForRange:[YYTextRange rangeWithRange:NSMakeRange(10,2)]];\n[layout selectionRectsForRange:[YYTextRange rangeWithRange:NSMakeRange(10,2)]];\n\t\n// 显示文本排版结果\nYYLabel *label = [YYLabel new];\nlabel.size = layout.textBoundingSize;\nlabel.textLayout = layout;\n```\n\t\n### 文本行位置调整\n```objc\n// 由于中文、英文、Emoji 等字体高度不一致，或者富文本中出现了不同字号的字体，\n// 可能会造成每行文字的高度不一致。这里可以添加一个修改器来实现固定行高，或者自定义文本行位置。\n  \n// 简单的方法:\n// 1. 创建一个文本行位置修改类，实现 `YYTextLinePositionModifier` 协议。\n// 2. 设置到 Label 或 TextView。\n\t\nYYTextLinePositionSimpleModifier *modifier = [YYTextLinePositionSimpleModifier new];\nmodifier.fixedLineHeight = 24;\n\t\nYYLabel *label = [YYLabel new];\nlabel.linePositionModifier = modifier;\n\t\n// 完全控制:\nYYTextLinePositionSimpleModifier *modifier = [YYTextLinePositionSimpleModifier new];\nmodifier.fixedLineHeight = 24;\n\t\nYYTextContainer *container = [YYTextContainer new];\ncontainer.size = CGSizeMake(100, CGFLOAT_MAX);\ncontainer.linePositionModifier = modifier;\n\t\nYYTextLayout *layout = [YYTextLayout layoutWithContainer:container text:text];\nYYLabel *label = [YYLabel new];\nlabel.size = layout.textBoundingSize;\nlabel.textLayout = layout;\n```\n\n### 异步排版和渲染\n```objc  \n// 如果你在显示字符串时有性能问题，可以这样开启异步模式：\nYYLabel *label = ...\nlabel.displaysAsynchronously = YES;\n    \n// 如果需要获得最高的性能，你可以在后台线程用 `YYTextLayout` 进行预排版： \nYYLabel *label = [YYLabel new];\nlabel.displaysAsynchronously = YES; //开启异步绘制\nlabel.ignoreCommonProperties = YES; //忽略除了 textLayout 之外的其他属性\n    \ndispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{\n   // 创建属性字符串\n   NSMutableAttributedString *text = [[NSMutableAttributedString alloc] initWithString:@\"Some Text\"];\n   text.yy_font = [UIFont systemFontOfSize:16];\n   text.yy_color = [UIColor grayColor];\n   [text yy_setColor:[UIColor redColor] range:NSMakeRange(0, 4)];\n \n   // 创建文本容器\n   YYTextContainer *container = [YYTextContainer new];\n   container.size = CGSizeMake(100, CGFLOAT_MAX);\n   container.maximumNumberOfRows = 0;\n   \n   // 生成排版结果\n   YYTextLayout *layout = [YYTextLayout layoutWithContainer:container text:text];\n   \n   dispatch_async(dispatch_get_main_queue(), ^{\n       label.size = layout.textBoundingSize;\n       label.textLayout = layout;\n   });\n});\n```\n\n### 文本容器控制\n```objc\nYYLabel *label = ...\nlabel.textContainerPath = [UIBezierPath bezierPathWith...];\nlabel.exclusionPaths = \t@[[UIBezierPath bezierPathWith...];,...];\nlabel.textContainerInset = UIEdgeInsetsMake(...);\nlabel.verticalForm = YES/NO;\n    \nYYTextView *textView = ...\ntextView.exclusionPaths = \t@[[UIBezierPath bezierPathWith...];,...];\ntextView.textContainerInset = UIEdgeInsetsMake(...);\ntextView.verticalForm = YES/NO;\n```    \n\n### 文本解析\n```objc\n// 1. 创建一个解析器\n\t\n// 内置简单的表情解析\nYYTextSimpleEmoticonParser *parser = [YYTextSimpleEmoticonParser new];\nNSMutableDictionary *mapper = [NSMutableDictionary new];\nmapper[@\":smile:\"] = [UIImage imageNamed:@\"smile.png\"];\nmapper[@\":cool:\"] = [UIImage imageNamed:@\"cool.png\"];\nmapper[@\":cry:\"] = [UIImage imageNamed:@\"cry.png\"];\nmapper[@\":wink:\"] = [UIImage imageNamed:@\"wink.png\"];\nparser.emoticonMapper = mapper;\n\t\n// 内置简单的 markdown 解析\nYYTextSimpleMarkdownParser *parser = [YYTextSimpleMarkdownParser new];\n[parser setColorWithDarkTheme];\n    \n// 实现 `YYTextParser` 协议的自定义解析器\nMyCustomParser *parser = ... \n    \n// 2. 把解析器添加到 YYLabel 或 YYTextView\nYYLabel *label = ...\nlabel.textParser = parser;\n    \nYYTextView *textView = ...\ntextView.textParser = parser;\n```\n\n### Debug\n```objc\n// 设置一个全局的 debug option 来显示排版结果。\nYYTextDebugOption *debugOptions = [YYTextDebugOption new];\ndebugOptions.baselineColor = [UIColor redColor];\ndebugOptions.CTFrameBorderColor = [UIColor redColor];\ndebugOptions.CTLineFillColor = [UIColor colorWithRed:0.000 green:0.463 blue:1.000 alpha:0.180];\ndebugOptions.CGGlyphBorderColor = [UIColor colorWithRed:1.000 green:0.524 blue:0.000 alpha:0.200];\n[YYTextDebugOption setSharedDebugOption:debugOptions];\n```\n\n### 更多示例\n查看演示工程 `Demo/YYTextDemo.xcodeproj`:\n\n\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Demo/DemoSnapshot/text_path.gif\" width=\"320\"\u003e\n\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Demo/DemoSnapshot/text_markdown.gif\" width=\"320\"\u003e\n\u003cbr/\u003e \u003cbr/\u003e\n\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Demo/DemoSnapshot/text_vertical.gif\" width=\"320\"\u003e\n\u003cimg src=\"https://raw.github.com/ibireme/YYText/master/Demo/DemoSnapshot/text_paste.gif\" width=\"320\"\u003e\n\n\n安装\n==============\n\n### CocoaPods\n\n1. 在 Podfile 中添加 `pod 'YYText'`。\n2. 执行 `pod install` 或 `pod update`。\n3. 导入 \\\u003cYYText/YYText.h\\\u003e。\n\n\n### Carthage\n\n1. 在 Cartfile 中添加 `github \"ibireme/YYText\"`。\n2. 执行 `carthage update --platform ios` 并将生成的 framework 添加到你的工程。\n3. 导入 \\\u003cYYText/YYText.h\\\u003e。\n\n\n### 手动安装\n\n1. 下载 YYText 文件夹内的所有内容。\n2. 将 YYText 内的源文件添加(拖放)到你的工程。\n3. 链接以下 frameworks:\n    * UIKit\n    * CoreFoundation\n    * CoreText\n    * QuartzCore\n    * Accelerate\n    * MobileCoreServices\n4. 导入 `YYText.h`。\n\n\n### 注意\n你可以添加 [YYImage](https://github.com/ibireme/YYImage) 或 [YYWebImage](https://github.com/ibireme/YYWebImage) 到你的工程，以支持动画格式(GIF/APNG/WebP)的图片。\n\n\n文档\n==============\n你可以在 [CocoaDocs](http://cocoadocs.org/docsets/YYText/) 查看在线 API 文档，也可以用 [appledoc](https://github.com/tomaz/appledoc) 本地生成文档。\n\n\n系统要求\n==============\n该项目最低支持 `iOS 6.0` 和 `Xcode 8.0`。\n\n\n已知问题\n==============\n* YYText 并不能支持所有 CoreText/TextKit 的属性，比如 NSBackgroundColor、NSStrikethrough、NSUnderline、NSAttachment、NSLink 等，但 YYText 中基本都有对应属性作为替代。详情见上方表格。\n* YYTextView 未实现局部刷新，所以在输入和编辑大量的文本（比如超过大概五千个汉字、或大概一万个英文字符）时会出现较明显的卡顿现象。\n* 竖排版时，添加 exclusionPaths 在少数情况下可能会导致文本显示空白。\n* 当添加了非矩形的 textContainerPath，并且有嵌入大于文本排版方向宽度的 RunDelegate 时，RunDelegate 之后的文字会无法显示。这是 CoreText 的 Bug（或者说是 Feature）。\n\n许可证\n==============\nYYText 使用 MIT 许可证，详情见 LICENSE 文件。\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fibireme%2FYYText","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fibireme%2FYYText","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fibireme%2FYYText/lists"}