New file |
| | |
| | | // |
| | | // YYLabel.h |
| | | // YYText <https://github.com/ibireme/YYText> |
| | | // |
| | | // Created by ibireme on 15/2/25. |
| | | // Copyright (c) 2015 ibireme. |
| | | // |
| | | // This source code is licensed under the MIT-style license found in the |
| | | // LICENSE file in the root directory of this source tree. |
| | | // |
| | | |
| | | #import <UIKit/UIKit.h> |
| | | |
| | | #if __has_include(<YYText/YYText.h>) |
| | | #import <YYText/YYTextParser.h> |
| | | #import <YYText/YYTextLayout.h> |
| | | #import <YYText/YYTextAttribute.h> |
| | | #else |
| | | #import "YYTextParser.h" |
| | | #import "YYTextLayout.h" |
| | | #import "YYTextAttribute.h" |
| | | #endif |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | #if !TARGET_INTERFACE_BUILDER |
| | | |
| | | /** |
| | | The YYLabel class implements a read-only text view. |
| | | |
| | | @discussion The API and behavior is similar to UILabel, but provides more features: |
| | | |
| | | * It supports asynchronous layout and rendering (to avoid blocking UI thread). |
| | | * It extends the CoreText attributes to support more text effects. |
| | | * It allows to add UIImage, UIView and CALayer as text attachments. |
| | | * It allows to add 'highlight' link to some range of text to allow user interact with. |
| | | * It allows to add container path and exclusion paths to control text container's shape. |
| | | * It supports vertical form layout to display CJK text. |
| | | |
| | | See NSAttributedString+YYText.h for more convenience methods to set the attributes. |
| | | See YYTextAttribute.h and YYTextLayout.h for more information. |
| | | */ |
| | | @interface YYLabel : UIView <NSCoding> |
| | | |
| | | #pragma mark - Accessing the Text Attributes |
| | | ///============================================================================= |
| | | /// @name Accessing the Text Attributes |
| | | ///============================================================================= |
| | | |
| | | /** |
| | | The text displayed by the label. Default is nil. |
| | | Set a new value to this property also replaces the text in `attributedText`. |
| | | Get the value returns the plain text in `attributedText`. |
| | | */ |
| | | @property (nullable, nonatomic, copy) NSString *text; |
| | | |
| | | /** |
| | | The font of the text. Default is 17-point system font. |
| | | Set a new value to this property also causes the new font to be applied to the entire `attributedText`. |
| | | Get the value returns the font at the head of `attributedText`. |
| | | */ |
| | | @property (null_resettable, nonatomic, strong) UIFont *font; |
| | | |
| | | /** |
| | | The color of the text. Default is black. |
| | | Set a new value to this property also causes the new color to be applied to the entire `attributedText`. |
| | | Get the value returns the color at the head of `attributedText`. |
| | | */ |
| | | @property (null_resettable, nonatomic, strong) UIColor *textColor; |
| | | |
| | | /** |
| | | The shadow color of the text. Default is nil. |
| | | Set a new value to this property also causes the shadow color to be applied to the entire `attributedText`. |
| | | Get the value returns the shadow color at the head of `attributedText`. |
| | | */ |
| | | @property (nullable, nonatomic, strong) UIColor *shadowColor; |
| | | |
| | | /** |
| | | The shadow offset of the text. Default is CGSizeZero. |
| | | Set a new value to this property also causes the shadow offset to be applied to the entire `attributedText`. |
| | | Get the value returns the shadow offset at the head of `attributedText`. |
| | | */ |
| | | @property (nonatomic) CGSize shadowOffset; |
| | | |
| | | /** |
| | | The shadow blur of the text. Default is 0. |
| | | Set a new value to this property also causes the shadow blur to be applied to the entire `attributedText`. |
| | | Get the value returns the shadow blur at the head of `attributedText`. |
| | | */ |
| | | @property (nonatomic) CGFloat shadowBlurRadius; |
| | | |
| | | /** |
| | | The technique to use for aligning the text. Default is NSTextAlignmentNatural. |
| | | Set a new value to this property also causes the new alignment to be applied to the entire `attributedText`. |
| | | Get the value returns the alignment at the head of `attributedText`. |
| | | */ |
| | | @property (nonatomic) NSTextAlignment textAlignment; |
| | | |
| | | /** |
| | | The text vertical aligmnent in container. Default is YYTextVerticalAlignmentCenter. |
| | | */ |
| | | @property (nonatomic) YYTextVerticalAlignment textVerticalAlignment; |
| | | |
| | | /** |
| | | The styled text displayed by the label. |
| | | Set a new value to this property also replaces the value of the `text`, `font`, `textColor`, |
| | | `textAlignment` and other properties in label. |
| | | |
| | | @discussion It only support the attributes declared in CoreText and YYTextAttribute. |
| | | See `NSAttributedString+YYText` for more convenience methods to set the attributes. |
| | | */ |
| | | @property (nullable, nonatomic, copy) NSAttributedString *attributedText; |
| | | |
| | | /** |
| | | The technique to use for wrapping and truncating the label's text. |
| | | Default is NSLineBreakByTruncatingTail. |
| | | */ |
| | | @property (nonatomic) NSLineBreakMode lineBreakMode; |
| | | |
| | | /** |
| | | The truncation token string used when text is truncated. Default is nil. |
| | | When the value is nil, the label use "…" as default truncation token. |
| | | */ |
| | | @property (nullable, nonatomic, copy) NSAttributedString *truncationToken; |
| | | |
| | | /** |
| | | The maximum number of lines to use for rendering text. Default value is 1. |
| | | 0 means no limit. |
| | | */ |
| | | @property (nonatomic) NSUInteger numberOfLines; |
| | | |
| | | /** |
| | | When `text` or `attributedText` is changed, the parser will be called to modify the text. |
| | | It can be used to add code highlighting or emoticon replacement to text view. |
| | | The default value is nil. |
| | | |
| | | See `YYTextParser` protocol for more information. |
| | | */ |
| | | @property (nullable, nonatomic, strong) id<YYTextParser> textParser; |
| | | |
| | | /** |
| | | The current text layout in text view. It can be used to query the text layout information. |
| | | Set a new value to this property also replaces most properties in this label, such as `text`, |
| | | `color`, `attributedText`, `lineBreakMode`, `textContainerPath`, `exclusionPaths` and so on. |
| | | */ |
| | | @property (nullable, nonatomic, strong) YYTextLayout *textLayout; |
| | | |
| | | |
| | | #pragma mark - Configuring the Text Container |
| | | ///============================================================================= |
| | | /// @name Configuring the Text Container |
| | | ///============================================================================= |
| | | |
| | | /** |
| | | A UIBezierPath object that specifies the shape of the text frame. Default value is nil. |
| | | */ |
| | | @property (nullable, nonatomic, copy) UIBezierPath *textContainerPath; |
| | | |
| | | /** |
| | | An array of UIBezierPath objects representing the exclusion paths inside the |
| | | receiver's bounding rectangle. Default value is nil. |
| | | */ |
| | | @property (nullable, nonatomic, copy) NSArray<UIBezierPath *> *exclusionPaths; |
| | | |
| | | /** |
| | | The inset of the text container's layout area within the text view's content area. |
| | | Default value is UIEdgeInsetsZero. |
| | | */ |
| | | @property (nonatomic) UIEdgeInsets textContainerInset; |
| | | |
| | | /** |
| | | Whether the receiver's layout orientation is vertical form. Default is NO. |
| | | It may used to display CJK text. |
| | | */ |
| | | @property (nonatomic, getter=isVerticalForm) BOOL verticalForm; |
| | | |
| | | /** |
| | | The text line position modifier used to modify the lines' position in layout. |
| | | Default value is nil. |
| | | See `YYTextLinePositionModifier` protocol for more information. |
| | | */ |
| | | @property (nullable, nonatomic, copy) id<YYTextLinePositionModifier> linePositionModifier; |
| | | |
| | | /** |
| | | The debug option to display CoreText layout result. |
| | | The default value is [YYTextDebugOption sharedDebugOption]. |
| | | */ |
| | | @property (nullable, nonatomic, copy) YYTextDebugOption *debugOption; |
| | | |
| | | |
| | | #pragma mark - Getting the Layout Constraints |
| | | ///============================================================================= |
| | | /// @name Getting the Layout Constraints |
| | | ///============================================================================= |
| | | |
| | | /** |
| | | The preferred maximum width (in points) for a multiline label. |
| | | |
| | | @discussion This property affects the size of the label when layout constraints |
| | | are applied to it. During layout, if the text extends beyond the width |
| | | specified by this property, the additional text is flowed to one or more new |
| | | lines, thereby increasing the height of the label. If the text is vertical |
| | | form, this value will match to text height. |
| | | */ |
| | | @property (nonatomic) CGFloat preferredMaxLayoutWidth; |
| | | |
| | | |
| | | #pragma mark - Interacting with Text Data |
| | | ///============================================================================= |
| | | /// @name Interacting with Text Data |
| | | ///============================================================================= |
| | | |
| | | /** |
| | | When user tap the label, this action will be called (similar to tap gesture). |
| | | The default value is nil. |
| | | */ |
| | | @property (nullable, nonatomic, copy) YYTextAction textTapAction; |
| | | |
| | | /** |
| | | When user long press the label, this action will be called (similar to long press gesture). |
| | | The default value is nil. |
| | | */ |
| | | @property (nullable, nonatomic, copy) YYTextAction textLongPressAction; |
| | | |
| | | /** |
| | | When user tap the highlight range of text, this action will be called. |
| | | The default value is nil. |
| | | */ |
| | | @property (nullable, nonatomic, copy) YYTextAction highlightTapAction; |
| | | |
| | | /** |
| | | When user long press the highlight range of text, this action will be called. |
| | | The default value is nil. |
| | | */ |
| | | @property (nullable, nonatomic, copy) YYTextAction highlightLongPressAction; |
| | | |
| | | |
| | | #pragma mark - Configuring the Display Mode |
| | | ///============================================================================= |
| | | /// @name Configuring the Display Mode |
| | | ///============================================================================= |
| | | |
| | | /** |
| | | A Boolean value indicating whether the layout and rendering codes are running |
| | | asynchronously on background threads. |
| | | |
| | | The default value is `NO`. |
| | | */ |
| | | @property (nonatomic) BOOL displaysAsynchronously; |
| | | |
| | | /** |
| | | If the value is YES, and the layer is rendered asynchronously, then it will |
| | | set label.layer.contents to nil before display. |
| | | |
| | | The default value is `YES`. |
| | | |
| | | @discussion When the asynchronously display is enabled, the layer's content will |
| | | be updated after the background render process finished. If the render process |
| | | can not finished in a vsync time (1/60 second), the old content will be still kept |
| | | for display. You may manually clear the content by set the layer.contents to nil |
| | | after you update the label's properties, or you can just set this property to YES. |
| | | */ |
| | | @property (nonatomic) BOOL clearContentsBeforeAsynchronouslyDisplay; |
| | | |
| | | /** |
| | | If the value is YES, and the layer is rendered asynchronously, then it will add |
| | | a fade animation on layer when the contents of layer changed. |
| | | |
| | | The default value is `YES`. |
| | | */ |
| | | @property (nonatomic) BOOL fadeOnAsynchronouslyDisplay; |
| | | |
| | | /** |
| | | If the value is YES, then it will add a fade animation on layer when some range |
| | | of text become highlighted. |
| | | |
| | | The default value is `YES`. |
| | | */ |
| | | @property (nonatomic) BOOL fadeOnHighlight; |
| | | |
| | | /** |
| | | Ignore common properties (such as text, font, textColor, attributedText...) and |
| | | only use "textLayout" to display content. |
| | | |
| | | The default value is `NO`. |
| | | |
| | | @discussion If you control the label content only through "textLayout", then |
| | | you may set this value to YES for higher performance. |
| | | */ |
| | | @property (nonatomic) BOOL ignoreCommonProperties; |
| | | |
| | | /* |
| | | Tips: |
| | | |
| | | 1. If you only need a UILabel alternative to display rich text and receive link touch event, |
| | | you do not need to adjust the display mode properties. |
| | | |
| | | 2. If you have performance issues, you may enable the asynchronous display mode |
| | | by setting the `displaysAsynchronously` to YES. |
| | | |
| | | 3. If you want to get the highest performance, you should do text layout with |
| | | `YYTextLayout` class in background thread. Here's an example: |
| | | |
| | | YYLabel *label = [YYLabel new]; |
| | | label.displaysAsynchronously = YES; |
| | | label.ignoreCommonProperties = YES; |
| | | |
| | | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ |
| | | |
| | | // Create attributed string. |
| | | 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)]; |
| | | |
| | | // Create text container |
| | | YYTextContainer *container = [YYTextContainer new]; |
| | | container.size = CGSizeMake(100, CGFLOAT_MAX); |
| | | container.maximumNumberOfRows = 0; |
| | | |
| | | // Generate a text layout. |
| | | YYTextLayout *layout = [YYTextLayout layoutWithContainer:container text:text]; |
| | | |
| | | dispatch_async(dispatch_get_main_queue(), ^{ |
| | | label.size = layout.textBoundingSize; |
| | | label.textLayout = layout; |
| | | }); |
| | | }); |
| | | |
| | | */ |
| | | |
| | | @end |
| | | |
| | | |
| | | #else // TARGET_INTERFACE_BUILDER |
| | | IB_DESIGNABLE |
| | | @interface YYLabel : UIView <NSCoding> |
| | | @property (nullable, nonatomic, copy) IBInspectable NSString *text; |
| | | @property (null_resettable, nonatomic, strong) IBInspectable UIColor *textColor; |
| | | @property (nullable, nonatomic, strong) IBInspectable NSString *fontName_; |
| | | @property (nonatomic) IBInspectable CGFloat fontSize_; |
| | | @property (nonatomic) IBInspectable BOOL fontIsBold_; |
| | | @property (nonatomic) IBInspectable NSUInteger numberOfLines; |
| | | @property (nonatomic) IBInspectable NSInteger lineBreakMode; |
| | | @property (nonatomic) IBInspectable CGFloat preferredMaxLayoutWidth; |
| | | @property (nonatomic, getter=isVerticalForm) IBInspectable BOOL verticalForm; |
| | | @property (nonatomic) IBInspectable NSInteger textAlignment; |
| | | @property (nonatomic) IBInspectable NSInteger textVerticalAlignment; |
| | | @property (nullable, nonatomic, strong) IBInspectable UIColor *shadowColor; |
| | | @property (nonatomic) IBInspectable CGPoint shadowOffset; |
| | | @property (nonatomic) IBInspectable CGFloat shadowBlurRadius; |
| | | @property (nullable, nonatomic, copy) IBInspectable NSAttributedString *attributedText; |
| | | @property (nonatomic) IBInspectable CGFloat insetTop_; |
| | | @property (nonatomic) IBInspectable CGFloat insetBottom_; |
| | | @property (nonatomic) IBInspectable CGFloat insetLeft_; |
| | | @property (nonatomic) IBInspectable CGFloat insetRight_; |
| | | @property (nonatomic) IBInspectable BOOL debugEnabled_; |
| | | |
| | | @property (null_resettable, nonatomic, strong) UIFont *font; |
| | | @property (nullable, nonatomic, copy) NSAttributedString *truncationToken; |
| | | @property (nullable, nonatomic, strong) id<YYTextParser> textParser; |
| | | @property (nullable, nonatomic, strong) YYTextLayout *textLayout; |
| | | @property (nullable, nonatomic, copy) UIBezierPath *textContainerPath; |
| | | @property (nullable, nonatomic, copy) NSArray<UIBezierPath*> *exclusionPaths; |
| | | @property (nonatomic) UIEdgeInsets textContainerInset; |
| | | @property (nullable, nonatomic, copy) id<YYTextLinePositionModifier> linePositionModifier; |
| | | @property (nonnull, nonatomic, copy) YYTextDebugOption *debugOption; |
| | | @property (nullable, nonatomic, copy) YYTextAction textTapAction; |
| | | @property (nullable, nonatomic, copy) YYTextAction textLongPressAction; |
| | | @property (nullable, nonatomic, copy) YYTextAction highlightTapAction; |
| | | @property (nullable, nonatomic, copy) YYTextAction highlightLongPressAction; |
| | | @property (nonatomic) BOOL displaysAsynchronously; |
| | | @property (nonatomic) BOOL clearContentsBeforeAsynchronouslyDisplay; |
| | | @property (nonatomic) BOOL fadeOnAsynchronouslyDisplay; |
| | | @property (nonatomic) BOOL fadeOnHighlight; |
| | | @property (nonatomic) BOOL ignoreCommonProperties; |
| | | @end |
| | | #endif // !TARGET_INTERFACE_BUILDER |
| | | |
| | | NS_ASSUME_NONNULL_END |