mirror of
https://github.com/status-im/react-native.git
synced 2025-02-26 16:10:58 +00:00
[React Native] #WIP Modify RCTShadowText measure function to honor maxNumberOfLines property
This commit is contained in:
parent
2aa52880b7
commit
397d4666d9
@ -23,7 +23,7 @@ extern NSString *const RCTReactTagAttributeName;
|
|||||||
@property (nonatomic, copy) NSString *fontStyle;
|
@property (nonatomic, copy) NSString *fontStyle;
|
||||||
@property (nonatomic, assign) BOOL isHighlighted;
|
@property (nonatomic, assign) BOOL isHighlighted;
|
||||||
@property (nonatomic, assign) CGFloat lineHeight;
|
@property (nonatomic, assign) CGFloat lineHeight;
|
||||||
@property (nonatomic, assign) NSInteger maxNumberOfLines;
|
@property (nonatomic, assign) NSUInteger maximumNumberOfLines;
|
||||||
@property (nonatomic, assign) CGSize shadowOffset;
|
@property (nonatomic, assign) CGSize shadowOffset;
|
||||||
@property (nonatomic, assign) NSTextAlignment textAlign;
|
@property (nonatomic, assign) NSTextAlignment textAlign;
|
||||||
|
|
||||||
@ -31,6 +31,8 @@ extern NSString *const RCTReactTagAttributeName;
|
|||||||
@property (nonatomic, strong) UIFont *font;
|
@property (nonatomic, strong) UIFont *font;
|
||||||
@property (nonatomic, assign) NSLineBreakMode truncationMode;
|
@property (nonatomic, assign) NSLineBreakMode truncationMode;
|
||||||
|
|
||||||
- (NSAttributedString *)attributedString;
|
@property (nonatomic, copy, readonly) NSAttributedString *attributedString;
|
||||||
|
@property (nonatomic, strong, readonly) NSLayoutManager *layoutManager;
|
||||||
|
@property (nonatomic, strong, readonly) NSTextContainer *textContainer;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@ -20,9 +20,17 @@ NSString *const RCTReactTagAttributeName = @"ReactTagAttributeName";
|
|||||||
static css_dim_t RCTMeasure(void *context, float width)
|
static css_dim_t RCTMeasure(void *context, float width)
|
||||||
{
|
{
|
||||||
RCTShadowText *shadowText = (__bridge RCTShadowText *)context;
|
RCTShadowText *shadowText = (__bridge RCTShadowText *)context;
|
||||||
CGSize computedSize = [[shadowText attributedString] boundingRectWithSize:(CGSize){isnan(width) ? CGFLOAT_MAX : width, CGFLOAT_MAX}
|
|
||||||
options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading
|
NSTextStorage *textStorage = [[NSTextStorage alloc] initWithAttributedString:[shadowText attributedString]];
|
||||||
context:nil].size;
|
[textStorage addLayoutManager:shadowText.layoutManager];
|
||||||
|
|
||||||
|
shadowText.textContainer.size = CGSizeMake(isnan(width) ? CGFLOAT_MAX : width, CGFLOAT_MAX);
|
||||||
|
shadowText.layoutManager.textStorage = textStorage;
|
||||||
|
[shadowText.layoutManager ensureLayoutForTextContainer:shadowText.textContainer];
|
||||||
|
|
||||||
|
CGSize computedSize = [shadowText.layoutManager usedRectForTextContainer:shadowText.textContainer].size;
|
||||||
|
|
||||||
|
[textStorage removeLayoutManager:shadowText.layoutManager];
|
||||||
|
|
||||||
css_dim_t result;
|
css_dim_t result;
|
||||||
result.dimensions[CSS_WIDTH] = RCTCeilPixelValue(computedSize.width);
|
result.dimensions[CSS_WIDTH] = RCTCeilPixelValue(computedSize.width);
|
||||||
@ -30,8 +38,9 @@ static css_dim_t RCTMeasure(void *context, float width)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@implementation RCTShadowText
|
@implementation RCTShadowText {
|
||||||
{
|
NSLayoutManager *_layoutManager;
|
||||||
|
NSTextContainer *_textContainer;
|
||||||
NSAttributedString *_cachedAttributedString;
|
NSAttributedString *_cachedAttributedString;
|
||||||
UIFont *_font;
|
UIFont *_font;
|
||||||
}
|
}
|
||||||
@ -41,7 +50,15 @@ static css_dim_t RCTMeasure(void *context, float width)
|
|||||||
if ((self = [super init])) {
|
if ((self = [super init])) {
|
||||||
_fontSize = NAN;
|
_fontSize = NAN;
|
||||||
_isHighlighted = NO;
|
_isHighlighted = NO;
|
||||||
|
|
||||||
|
_textContainer = [[NSTextContainer alloc] init];
|
||||||
|
_textContainer.lineBreakMode = NSLineBreakByTruncatingTail;
|
||||||
|
_textContainer.lineFragmentPadding = 0.0;
|
||||||
|
|
||||||
|
_layoutManager = [[NSLayoutManager alloc] init];
|
||||||
|
[_layoutManager addTextContainer:_textContainer];
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -201,11 +218,31 @@ RCT_TEXT_PROPERTY(FontFamily, _fontFamily, NSString *);
|
|||||||
RCT_TEXT_PROPERTY(FontSize, _fontSize, CGFloat);
|
RCT_TEXT_PROPERTY(FontSize, _fontSize, CGFloat);
|
||||||
RCT_TEXT_PROPERTY(FontWeight, _fontWeight, NSString *);
|
RCT_TEXT_PROPERTY(FontWeight, _fontWeight, NSString *);
|
||||||
RCT_TEXT_PROPERTY(LineHeight, _lineHeight, CGFloat);
|
RCT_TEXT_PROPERTY(LineHeight, _lineHeight, CGFloat);
|
||||||
RCT_TEXT_PROPERTY(MaxNumberOfLines, _maxNumberOfLines, NSInteger);
|
|
||||||
RCT_TEXT_PROPERTY(ShadowOffset, _shadowOffset, CGSize);
|
RCT_TEXT_PROPERTY(ShadowOffset, _shadowOffset, CGSize);
|
||||||
RCT_TEXT_PROPERTY(TextAlign, _textAlign, NSTextAlignment);
|
RCT_TEXT_PROPERTY(TextAlign, _textAlign, NSTextAlignment);
|
||||||
RCT_TEXT_PROPERTY(TruncationMode, _truncationMode, NSLineBreakMode);
|
|
||||||
RCT_TEXT_PROPERTY(IsHighlighted, _isHighlighted, BOOL);
|
RCT_TEXT_PROPERTY(IsHighlighted, _isHighlighted, BOOL);
|
||||||
RCT_TEXT_PROPERTY(Font, _font, UIFont *);
|
RCT_TEXT_PROPERTY(Font, _font, UIFont *);
|
||||||
|
|
||||||
|
- (NSLineBreakMode)truncationMode
|
||||||
|
{
|
||||||
|
return _textContainer.lineBreakMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setTruncationMode:(NSLineBreakMode)truncationMode
|
||||||
|
{
|
||||||
|
_textContainer.lineBreakMode = truncationMode;
|
||||||
|
[self dirtyText];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSUInteger)maximumNumberOfLines
|
||||||
|
{
|
||||||
|
return _textContainer.maximumNumberOfLines;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setMaximumNumberOfLines:(NSUInteger)maximumNumberOfLines
|
||||||
|
{
|
||||||
|
_textContainer.maximumNumberOfLines = maximumNumberOfLines;
|
||||||
|
[self dirtyText];
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@ -11,9 +11,10 @@
|
|||||||
|
|
||||||
@interface RCTText : UIView
|
@interface RCTText : UIView
|
||||||
|
|
||||||
|
@property (nonatomic, strong) NSLayoutManager *layoutManager;
|
||||||
|
@property (nonatomic, strong) NSTextContainer *textContainer;
|
||||||
@property (nonatomic, copy) NSAttributedString *attributedText;
|
@property (nonatomic, copy) NSAttributedString *attributedText;
|
||||||
@property (nonatomic, assign) NSLineBreakMode lineBreakMode;
|
|
||||||
@property (nonatomic, assign) NSUInteger numberOfLines;
|
|
||||||
@property (nonatomic, assign) UIEdgeInsets contentInset;
|
@property (nonatomic, assign) UIEdgeInsets contentInset;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@ -23,15 +23,7 @@
|
|||||||
- (instancetype)initWithFrame:(CGRect)frame
|
- (instancetype)initWithFrame:(CGRect)frame
|
||||||
{
|
{
|
||||||
if ((self = [super initWithFrame:frame])) {
|
if ((self = [super initWithFrame:frame])) {
|
||||||
_textContainer = [[NSTextContainer alloc] init];
|
|
||||||
_textContainer.lineBreakMode = NSLineBreakByTruncatingTail;
|
|
||||||
_textContainer.lineFragmentPadding = 0.0;
|
|
||||||
|
|
||||||
_layoutManager = [[NSLayoutManager alloc] init];
|
|
||||||
[_layoutManager addTextContainer:_textContainer];
|
|
||||||
|
|
||||||
_textStorage = [[NSTextStorage alloc] init];
|
_textStorage = [[NSTextStorage alloc] init];
|
||||||
[_textStorage addLayoutManager:_layoutManager];
|
|
||||||
|
|
||||||
self.contentMode = UIViewContentModeRedraw;
|
self.contentMode = UIViewContentModeRedraw;
|
||||||
}
|
}
|
||||||
@ -50,25 +42,31 @@
|
|||||||
[self setNeedsDisplay];
|
[self setNeedsDisplay];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSUInteger)numberOfLines
|
- (void)setTextContainer:(NSTextContainer *)textContainer
|
||||||
{
|
{
|
||||||
return _textContainer.maximumNumberOfLines;
|
if ([_textContainer isEqual:textContainer]) return;
|
||||||
}
|
|
||||||
|
_textContainer = textContainer;
|
||||||
|
|
||||||
|
for (NSInteger i = _layoutManager.textContainers.count - 1; i >= 0; i--) {
|
||||||
|
[_layoutManager removeTextContainerAtIndex:i];
|
||||||
|
}
|
||||||
|
[_layoutManager addTextContainer:_textContainer];
|
||||||
|
|
||||||
- (void)setNumberOfLines:(NSUInteger)numberOfLines
|
|
||||||
{
|
|
||||||
_textContainer.maximumNumberOfLines = numberOfLines;
|
|
||||||
[self setNeedsDisplay];
|
[self setNeedsDisplay];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSLineBreakMode)lineBreakMode
|
- (void)setLayoutManager:(NSLayoutManager *)layoutManager
|
||||||
{
|
{
|
||||||
return _textContainer.lineBreakMode;
|
if ([_layoutManager isEqual:layoutManager]) return;
|
||||||
}
|
|
||||||
|
_layoutManager = layoutManager;
|
||||||
|
|
||||||
|
for (NSLayoutManager *layoutManager in _textStorage.layoutManagers) {
|
||||||
|
[_textStorage removeLayoutManager:layoutManager];
|
||||||
|
}
|
||||||
|
[_textStorage addLayoutManager:_layoutManager];
|
||||||
|
|
||||||
- (void)setLineBreakMode:(NSLineBreakMode)lineBreakMode
|
|
||||||
{
|
|
||||||
_textContainer.lineBreakMode = lineBreakMode;
|
|
||||||
[self setNeedsDisplay];
|
[self setNeedsDisplay];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,15 +33,6 @@
|
|||||||
#pragma mark - View properties
|
#pragma mark - View properties
|
||||||
|
|
||||||
RCT_REMAP_VIEW_PROPERTY(containerBackgroundColor, backgroundColor, UIColor)
|
RCT_REMAP_VIEW_PROPERTY(containerBackgroundColor, backgroundColor, UIColor)
|
||||||
RCT_CUSTOM_VIEW_PROPERTY(numberOfLines, NSInteger, RCTText)
|
|
||||||
{
|
|
||||||
NSLineBreakMode truncationMode = NSLineBreakByClipping;
|
|
||||||
view.numberOfLines = json ? [RCTConvert NSInteger:json] : defaultView.numberOfLines;
|
|
||||||
if (view.numberOfLines > 0) {
|
|
||||||
truncationMode = NSLineBreakByTruncatingTail;
|
|
||||||
}
|
|
||||||
view.lineBreakMode = truncationMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark - Shadow properties
|
#pragma mark - Shadow properties
|
||||||
|
|
||||||
@ -65,8 +56,8 @@ RCT_CUSTOM_SHADOW_PROPERTY(containerBackgroundColor, UIColor, RCTShadowText)
|
|||||||
RCT_CUSTOM_SHADOW_PROPERTY(numberOfLines, NSInteger, RCTShadowText)
|
RCT_CUSTOM_SHADOW_PROPERTY(numberOfLines, NSInteger, RCTShadowText)
|
||||||
{
|
{
|
||||||
NSLineBreakMode truncationMode = NSLineBreakByClipping;
|
NSLineBreakMode truncationMode = NSLineBreakByClipping;
|
||||||
view.maxNumberOfLines = json ? [RCTConvert NSInteger:json] : defaultView.maxNumberOfLines;
|
view.maximumNumberOfLines = json ? [RCTConvert NSInteger:json] : defaultView.maximumNumberOfLines;
|
||||||
if (view.maxNumberOfLines > 0) {
|
if (view.maximumNumberOfLines > 0) {
|
||||||
truncationMode = NSLineBreakByTruncatingTail;
|
truncationMode = NSLineBreakByTruncatingTail;
|
||||||
}
|
}
|
||||||
view.truncationMode = truncationMode;
|
view.truncationMode = truncationMode;
|
||||||
@ -124,12 +115,16 @@ RCT_CUSTOM_SHADOW_PROPERTY(numberOfLines, NSInteger, RCTShadowText)
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
- (RCTViewManagerUIBlock)uiBlockToAmendWithShadowView:(RCTShadowView *)shadowView
|
- (RCTViewManagerUIBlock)uiBlockToAmendWithShadowView:(RCTShadowText *)shadowView
|
||||||
{
|
{
|
||||||
NSNumber *reactTag = shadowView.reactTag;
|
NSNumber *reactTag = shadowView.reactTag;
|
||||||
UIEdgeInsets padding = shadowView.paddingAsInsets;
|
UIEdgeInsets padding = shadowView.paddingAsInsets;
|
||||||
|
|
||||||
return ^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) {
|
return ^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) {
|
||||||
((RCTText *)viewRegistry[reactTag]).contentInset = padding;
|
RCTText *text = (RCTText *)viewRegistry[reactTag];
|
||||||
|
text.contentInset = padding;
|
||||||
|
text.layoutManager = shadowView.layoutManager;
|
||||||
|
text.textContainer = shadowView.textContainer;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user