mirror of
https://github.com/status-im/react-native.git
synced 2025-02-26 08:05:34 +00:00
Initial implementation of adjustsFontSizeToFit.
Summary: Closes https://github.com/facebook/react-native/pull/4026 Differential Revision: D2678492 Pulled By: nicklockwood fbshipit-source-id: 0467814f810fee997ac50960ffb1daa74d52acba
This commit is contained in:
parent
6775d1f136
commit
c6b6f53ae7
@ -29,6 +29,7 @@ var {
|
|||||||
StyleSheet,
|
StyleSheet,
|
||||||
Text,
|
Text,
|
||||||
View,
|
View,
|
||||||
|
LayoutAnimation,
|
||||||
} = ReactNative;
|
} = ReactNative;
|
||||||
|
|
||||||
class Entity extends React.Component {
|
class Entity extends React.Component {
|
||||||
@ -81,6 +82,86 @@ class AttributeToggler extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var AdjustingFontSize = React.createClass({
|
||||||
|
getInitialState: function() {
|
||||||
|
return {dynamicText:'', shouldRender: true,};
|
||||||
|
},
|
||||||
|
reset: function() {
|
||||||
|
LayoutAnimation.easeInEaseOut();
|
||||||
|
this.setState({
|
||||||
|
shouldRender: false,
|
||||||
|
});
|
||||||
|
setTimeout(()=>{
|
||||||
|
LayoutAnimation.easeInEaseOut();
|
||||||
|
this.setState({
|
||||||
|
dynamicText: '',
|
||||||
|
shouldRender: true,
|
||||||
|
});
|
||||||
|
}, 300);
|
||||||
|
},
|
||||||
|
addText: function() {
|
||||||
|
this.setState({
|
||||||
|
dynamicText: this.state.dynamicText + (Math.floor((Math.random() * 10) % 2) ? ' foo' : ' bar'),
|
||||||
|
});
|
||||||
|
},
|
||||||
|
removeText: function() {
|
||||||
|
this.setState({
|
||||||
|
dynamicText: this.state.dynamicText.slice(0, this.state.dynamicText.length - 4),
|
||||||
|
});
|
||||||
|
},
|
||||||
|
render: function() {
|
||||||
|
|
||||||
|
if (!this.state.shouldRender) {
|
||||||
|
return (<View/>);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<View>
|
||||||
|
<Text lineBreakMode="tail" numberOfLines={1} style={{fontSize: 36, marginVertical:6}}>
|
||||||
|
Truncated text is baaaaad.
|
||||||
|
</Text>
|
||||||
|
<Text numberOfLines={1} adjustsFontSizeToFit={true} style={{fontSize: 40, marginVertical:6}}>
|
||||||
|
Shrinking to fit available space is much better!
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<Text adjustsFontSizeToFit={true} numberOfLines={1} style={{fontSize:30, marginVertical:6}}>
|
||||||
|
{'Add text to me to watch me shrink!' + ' ' + this.state.dynamicText}
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<Text adjustsFontSizeToFit={true} numberOfLines={4} style={{fontSize:20, marginVertical:6}}>
|
||||||
|
{'Multiline text component shrinking is supported, watch as this reeeeaaaally loooooong teeeeeeext grooooows and then shriiiinks as you add text to me! ioahsdia soady auydoa aoisyd aosdy ' + ' ' + this.state.dynamicText}
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<Text adjustsFontSizeToFit={true} numberOfLines={1} style={{marginVertical:6}}>
|
||||||
|
<Text style={{fontSize:14}}>
|
||||||
|
{'Differently sized nested elements will shrink together. '}
|
||||||
|
</Text>
|
||||||
|
<Text style={{fontSize:20}}>
|
||||||
|
{'LARGE TEXT! ' + this.state.dynamicText}
|
||||||
|
</Text>
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<View style={{flexDirection:'row', justifyContent:'space-around', marginTop: 5, marginVertical:6}}>
|
||||||
|
<Text
|
||||||
|
style={{backgroundColor: '#ffaaaa'}}
|
||||||
|
onPress={this.reset}>
|
||||||
|
Reset
|
||||||
|
</Text>
|
||||||
|
<Text
|
||||||
|
style={{backgroundColor: '#aaaaff'}}
|
||||||
|
onPress={this.removeText}>
|
||||||
|
Remove Text
|
||||||
|
</Text>
|
||||||
|
<Text
|
||||||
|
style={{backgroundColor: '#aaffaa'}}
|
||||||
|
onPress={this.addText}>
|
||||||
|
Add Text
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
exports.title = '<Text>';
|
exports.title = '<Text>';
|
||||||
exports.description = 'Base component for rendering styled text.';
|
exports.description = 'Base component for rendering styled text.';
|
||||||
exports.displayName = 'TextExample';
|
exports.displayName = 'TextExample';
|
||||||
@ -492,6 +573,11 @@ exports.examples = [
|
|||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
}, {
|
||||||
|
title: 'Dynamic Font Size Adjustment',
|
||||||
|
render: function(): ReactElement<any> {
|
||||||
|
return <AdjustingFontSize />;
|
||||||
|
},
|
||||||
}];
|
}];
|
||||||
|
|
||||||
var styles = StyleSheet.create({
|
var styles = StyleSheet.create({
|
||||||
|
@ -10,6 +10,14 @@
|
|||||||
#import "RCTShadowView.h"
|
#import "RCTShadowView.h"
|
||||||
#import "RCTTextDecorationLineType.h"
|
#import "RCTTextDecorationLineType.h"
|
||||||
|
|
||||||
|
typedef NS_ENUM(NSInteger, RCTSizeComparison)
|
||||||
|
{
|
||||||
|
RCTSizeTooLarge,
|
||||||
|
RCTSizeTooSmall,
|
||||||
|
RCTSizeWithinRange,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
extern NSString *const RCTIsHighlightedAttributeName;
|
extern NSString *const RCTIsHighlightedAttributeName;
|
||||||
extern NSString *const RCTReactTagAttributeName;
|
extern NSString *const RCTReactTagAttributeName;
|
||||||
|
|
||||||
@ -38,6 +46,8 @@ extern NSString *const RCTReactTagAttributeName;
|
|||||||
@property (nonatomic, assign) CGSize textShadowOffset;
|
@property (nonatomic, assign) CGSize textShadowOffset;
|
||||||
@property (nonatomic, assign) CGFloat textShadowRadius;
|
@property (nonatomic, assign) CGFloat textShadowRadius;
|
||||||
@property (nonatomic, strong) UIColor *textShadowColor;
|
@property (nonatomic, strong) UIColor *textShadowColor;
|
||||||
|
@property (nonatomic, assign) BOOL adjustsFontSizeToFit;
|
||||||
|
@property (nonatomic, assign) CGFloat minimumFontScale;
|
||||||
|
|
||||||
- (void)recomputeText;
|
- (void)recomputeText;
|
||||||
|
|
||||||
|
@ -24,6 +24,11 @@ NSString *const RCTShadowViewAttributeName = @"RCTShadowViewAttributeName";
|
|||||||
NSString *const RCTIsHighlightedAttributeName = @"IsHighlightedAttributeName";
|
NSString *const RCTIsHighlightedAttributeName = @"IsHighlightedAttributeName";
|
||||||
NSString *const RCTReactTagAttributeName = @"ReactTagAttributeName";
|
NSString *const RCTReactTagAttributeName = @"ReactTagAttributeName";
|
||||||
|
|
||||||
|
CGFloat const RCTTextAutoSizeDefaultMinimumFontScale = 0.5f;
|
||||||
|
CGFloat const RCTTextAutoSizeWidthErrorMargin = 0.05f;
|
||||||
|
CGFloat const RCTTextAutoSizeHeightErrorMargin = 0.025f;
|
||||||
|
CGFloat const RCTTextAutoSizeGranularity = 0.001f;
|
||||||
|
|
||||||
@implementation RCTShadowText
|
@implementation RCTShadowText
|
||||||
{
|
{
|
||||||
NSTextStorage *_cachedTextStorage;
|
NSTextStorage *_cachedTextStorage;
|
||||||
@ -37,6 +42,7 @@ static CSSSize RCTMeasure(void *context, float width, CSSMeasureMode widthMode,
|
|||||||
{
|
{
|
||||||
RCTShadowText *shadowText = (__bridge RCTShadowText *)context;
|
RCTShadowText *shadowText = (__bridge RCTShadowText *)context;
|
||||||
NSTextStorage *textStorage = [shadowText buildTextStorageForWidth:width widthMode:widthMode];
|
NSTextStorage *textStorage = [shadowText buildTextStorageForWidth:width widthMode:widthMode];
|
||||||
|
[shadowText calculateTextFrame:textStorage];
|
||||||
NSLayoutManager *layoutManager = textStorage.layoutManagers.firstObject;
|
NSLayoutManager *layoutManager = textStorage.layoutManagers.firstObject;
|
||||||
NSTextContainer *textContainer = layoutManager.textContainers.firstObject;
|
NSTextContainer *textContainer = layoutManager.textContainers.firstObject;
|
||||||
CGSize computedSize = [layoutManager usedRectForTextContainer:textContainer].size;
|
CGSize computedSize = [layoutManager usedRectForTextContainer:textContainer].size;
|
||||||
@ -105,10 +111,13 @@ static CSSSize RCTMeasure(void *context, float width, CSSMeasureMode widthMode,
|
|||||||
UIEdgeInsets padding = self.paddingAsInsets;
|
UIEdgeInsets padding = self.paddingAsInsets;
|
||||||
CGFloat width = self.frame.size.width - (padding.left + padding.right);
|
CGFloat width = self.frame.size.width - (padding.left + padding.right);
|
||||||
|
|
||||||
|
|
||||||
NSNumber *parentTag = [[self reactSuperview] reactTag];
|
NSNumber *parentTag = [[self reactSuperview] reactTag];
|
||||||
NSTextStorage *textStorage = [self buildTextStorageForWidth:width widthMode:CSSMeasureModeExactly];
|
NSTextStorage *textStorage = [self buildTextStorageForWidth:width widthMode:CSSMeasureModeExactly];
|
||||||
|
CGRect textFrame = [self calculateTextFrame:textStorage];
|
||||||
[applierBlocks addObject:^(NSDictionary<NSNumber *, UIView *> *viewRegistry) {
|
[applierBlocks addObject:^(NSDictionary<NSNumber *, UIView *> *viewRegistry) {
|
||||||
RCTText *view = (RCTText *)viewRegistry[self.reactTag];
|
RCTText *view = (RCTText *)viewRegistry[self.reactTag];
|
||||||
|
view.textFrame = textFrame;
|
||||||
view.textStorage = textStorage;
|
view.textStorage = textStorage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -452,6 +461,155 @@ static CSSSize RCTMeasure(void *context, float width, CSSMeasureMode widthMode,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma mark Autosizing
|
||||||
|
|
||||||
|
- (CGRect)calculateTextFrame:(NSTextStorage *)textStorage
|
||||||
|
{
|
||||||
|
CGRect textFrame = UIEdgeInsetsInsetRect((CGRect){CGPointZero, self.frame.size},
|
||||||
|
self.paddingAsInsets);
|
||||||
|
|
||||||
|
|
||||||
|
if (_adjustsFontSizeToFit) {
|
||||||
|
textFrame = [self updateStorage:textStorage toFitFrame:textFrame];
|
||||||
|
}
|
||||||
|
|
||||||
|
return textFrame;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (CGRect)updateStorage:(NSTextStorage *)textStorage toFitFrame:(CGRect)frame
|
||||||
|
{
|
||||||
|
|
||||||
|
BOOL fits = [self attemptScale:1.0f
|
||||||
|
inStorage:textStorage
|
||||||
|
forFrame:frame];
|
||||||
|
CGSize requiredSize;
|
||||||
|
if (!fits) {
|
||||||
|
requiredSize = [self calculateOptimumScaleInFrame:frame
|
||||||
|
forStorage:textStorage
|
||||||
|
minScale:self.minimumFontScale
|
||||||
|
maxScale:1.0
|
||||||
|
prevMid:INT_MAX];
|
||||||
|
} else {
|
||||||
|
requiredSize = [self calculateSize:textStorage];
|
||||||
|
}
|
||||||
|
|
||||||
|
//Vertically center draw position for new text sizing.
|
||||||
|
frame.origin.y = self.paddingAsInsets.top + RCTRoundPixelValue((CGRectGetHeight(frame) - requiredSize.height) / 2.0f);
|
||||||
|
return frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (CGSize)calculateOptimumScaleInFrame:(CGRect)frame
|
||||||
|
forStorage:(NSTextStorage *)textStorage
|
||||||
|
minScale:(CGFloat)minScale
|
||||||
|
maxScale:(CGFloat)maxScale
|
||||||
|
prevMid:(CGFloat)prevMid
|
||||||
|
{
|
||||||
|
CGFloat midScale = (minScale + maxScale) / 2.0f;
|
||||||
|
if (round((prevMid / RCTTextAutoSizeGranularity)) == round((midScale / RCTTextAutoSizeGranularity))) {
|
||||||
|
//Bail because we can't meet error margin.
|
||||||
|
return [self calculateSize:textStorage];
|
||||||
|
} else {
|
||||||
|
RCTSizeComparison comparison = [self attemptScale:midScale
|
||||||
|
inStorage:textStorage
|
||||||
|
forFrame:frame];
|
||||||
|
if (comparison == RCTSizeWithinRange) {
|
||||||
|
return [self calculateSize:textStorage];
|
||||||
|
} else if (comparison == RCTSizeTooLarge) {
|
||||||
|
return [self calculateOptimumScaleInFrame:frame
|
||||||
|
forStorage:textStorage
|
||||||
|
minScale:minScale
|
||||||
|
maxScale:midScale - RCTTextAutoSizeGranularity
|
||||||
|
prevMid:midScale];
|
||||||
|
} else {
|
||||||
|
return [self calculateOptimumScaleInFrame:frame
|
||||||
|
forStorage:textStorage
|
||||||
|
minScale:midScale + RCTTextAutoSizeGranularity
|
||||||
|
maxScale:maxScale
|
||||||
|
prevMid:midScale];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (RCTSizeComparison)attemptScale:(CGFloat)scale
|
||||||
|
inStorage:(NSTextStorage *)textStorage
|
||||||
|
forFrame:(CGRect)frame
|
||||||
|
{
|
||||||
|
NSLayoutManager *layoutManager = [textStorage.layoutManagers firstObject];
|
||||||
|
NSTextContainer *textContainer = [layoutManager.textContainers firstObject];
|
||||||
|
|
||||||
|
NSRange glyphRange = NSMakeRange(0, textStorage.length);
|
||||||
|
[textStorage beginEditing];
|
||||||
|
[textStorage enumerateAttribute:NSFontAttributeName
|
||||||
|
inRange:glyphRange
|
||||||
|
options:0
|
||||||
|
usingBlock:^(UIFont *font, NSRange range, BOOL *stop)
|
||||||
|
{
|
||||||
|
if (font) {
|
||||||
|
UIFont *originalFont = [self.attributedString attribute:NSFontAttributeName
|
||||||
|
atIndex:range.location
|
||||||
|
effectiveRange:&range];
|
||||||
|
UIFont *newFont = [font fontWithSize:originalFont.pointSize * scale];
|
||||||
|
[textStorage removeAttribute:NSFontAttributeName range:range];
|
||||||
|
[textStorage addAttribute:NSFontAttributeName value:newFont range:range];
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
|
||||||
|
[textStorage endEditing];
|
||||||
|
|
||||||
|
NSInteger linesRequired = [self numberOfLinesRequired:[textStorage.layoutManagers firstObject]];
|
||||||
|
CGSize requiredSize = [self calculateSize:textStorage];
|
||||||
|
|
||||||
|
BOOL fitSize = requiredSize.height <= CGRectGetHeight(frame) &&
|
||||||
|
requiredSize.width <= CGRectGetWidth(frame);
|
||||||
|
|
||||||
|
BOOL fitLines = linesRequired <= textContainer.maximumNumberOfLines ||
|
||||||
|
textContainer.maximumNumberOfLines == 0;
|
||||||
|
|
||||||
|
if (fitLines && fitSize) {
|
||||||
|
if ((requiredSize.width + (CGRectGetWidth(frame) * RCTTextAutoSizeWidthErrorMargin)) > CGRectGetWidth(frame) &&
|
||||||
|
(requiredSize.height + (CGRectGetHeight(frame) * RCTTextAutoSizeHeightErrorMargin)) > CGRectGetHeight(frame))
|
||||||
|
{
|
||||||
|
return RCTSizeWithinRange;
|
||||||
|
} else {
|
||||||
|
return RCTSizeTooSmall;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return RCTSizeTooLarge;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Via Apple Text Layout Programming Guide
|
||||||
|
// https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/TextLayout/Tasks/CountLines.html
|
||||||
|
- (NSInteger)numberOfLinesRequired:(NSLayoutManager *)layoutManager
|
||||||
|
{
|
||||||
|
NSInteger numberOfLines, index, numberOfGlyphs = [layoutManager numberOfGlyphs];
|
||||||
|
NSRange lineRange;
|
||||||
|
for (numberOfLines = 0, index = 0; index < numberOfGlyphs; numberOfLines++){
|
||||||
|
(void) [layoutManager lineFragmentRectForGlyphAtIndex:index
|
||||||
|
effectiveRange:&lineRange];
|
||||||
|
index = NSMaxRange(lineRange);
|
||||||
|
}
|
||||||
|
|
||||||
|
return numberOfLines;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Via Apple Text Layout Programming Guide
|
||||||
|
//https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/TextLayout/Tasks/StringHeight.html
|
||||||
|
- (CGSize)calculateSize:(NSTextStorage *)storage
|
||||||
|
{
|
||||||
|
NSLayoutManager *layoutManager = [storage.layoutManagers firstObject];
|
||||||
|
NSTextContainer *textContainer = [layoutManager.textContainers firstObject];
|
||||||
|
|
||||||
|
[textContainer setLineBreakMode:NSLineBreakByWordWrapping];
|
||||||
|
NSInteger maxLines = [textContainer maximumNumberOfLines];
|
||||||
|
[textContainer setMaximumNumberOfLines:0];
|
||||||
|
(void) [layoutManager glyphRangeForTextContainer:textContainer];
|
||||||
|
CGSize requiredSize = [layoutManager usedRectForTextContainer:textContainer].size;
|
||||||
|
[textContainer setMaximumNumberOfLines:maxLines];
|
||||||
|
|
||||||
|
return requiredSize;
|
||||||
|
}
|
||||||
|
|
||||||
- (void)setBackgroundColor:(UIColor *)backgroundColor
|
- (void)setBackgroundColor:(UIColor *)backgroundColor
|
||||||
{
|
{
|
||||||
super.backgroundColor = backgroundColor;
|
super.backgroundColor = backgroundColor;
|
||||||
@ -465,6 +623,7 @@ static CSSSize RCTMeasure(void *context, float width, CSSMeasureMode widthMode,
|
|||||||
[self dirtyText]; \
|
[self dirtyText]; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RCT_TEXT_PROPERTY(AdjustsFontSizeToFit, _adjustsFontSizeToFit, BOOL)
|
||||||
RCT_TEXT_PROPERTY(Color, _color, UIColor *)
|
RCT_TEXT_PROPERTY(Color, _color, UIColor *)
|
||||||
RCT_TEXT_PROPERTY(FontFamily, _fontFamily, NSString *)
|
RCT_TEXT_PROPERTY(FontFamily, _fontFamily, NSString *)
|
||||||
RCT_TEXT_PROPERTY(FontSize, _fontSize, CGFloat)
|
RCT_TEXT_PROPERTY(FontSize, _fontSize, CGFloat)
|
||||||
@ -512,4 +671,12 @@ RCT_TEXT_PROPERTY(TextShadowColor, _textShadowColor, UIColor *);
|
|||||||
[self dirtyText];
|
[self dirtyText];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)setMinimumFontScale:(CGFloat)minimumFontScale
|
||||||
|
{
|
||||||
|
if (minimumFontScale >= 0.01) {
|
||||||
|
_minimumFontScale = minimumFontScale;
|
||||||
|
}
|
||||||
|
[self dirtyText];
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@ -13,5 +13,7 @@
|
|||||||
|
|
||||||
@property (nonatomic, assign) UIEdgeInsets contentInset;
|
@property (nonatomic, assign) UIEdgeInsets contentInset;
|
||||||
@property (nonatomic, strong) NSTextStorage *textStorage;
|
@property (nonatomic, strong) NSTextStorage *textStorage;
|
||||||
|
@property (nonatomic, assign) CGRect textFrame;
|
||||||
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@ -34,7 +34,6 @@ static void collectNonTextDescendants(RCTText *view, NSMutableArray *nonTextDesc
|
|||||||
{
|
{
|
||||||
if ((self = [super initWithFrame:frame])) {
|
if ((self = [super initWithFrame:frame])) {
|
||||||
_textStorage = [NSTextStorage new];
|
_textStorage = [NSTextStorage new];
|
||||||
|
|
||||||
self.isAccessibilityElement = YES;
|
self.isAccessibilityElement = YES;
|
||||||
self.accessibilityTraits |= UIAccessibilityTraitStaticText;
|
self.accessibilityTraits |= UIAccessibilityTraitStaticText;
|
||||||
|
|
||||||
@ -97,11 +96,11 @@ static void collectNonTextDescendants(RCTText *view, NSMutableArray *nonTextDesc
|
|||||||
|
|
||||||
- (void)drawRect:(CGRect)rect
|
- (void)drawRect:(CGRect)rect
|
||||||
{
|
{
|
||||||
NSLayoutManager *layoutManager = _textStorage.layoutManagers.firstObject;
|
NSLayoutManager *layoutManager = [_textStorage.layoutManagers firstObject];
|
||||||
NSTextContainer *textContainer = layoutManager.textContainers.firstObject;
|
NSTextContainer *textContainer = [layoutManager.textContainers firstObject];
|
||||||
CGRect textFrame = UIEdgeInsetsInsetRect(self.bounds, _contentInset);
|
|
||||||
NSRange glyphRange = [layoutManager glyphRangeForTextContainer:textContainer];
|
|
||||||
|
|
||||||
|
NSRange glyphRange = [layoutManager glyphRangeForTextContainer:textContainer];
|
||||||
|
CGRect textFrame = self.textFrame;
|
||||||
[layoutManager drawBackgroundForGlyphRange:glyphRange atPoint:textFrame.origin];
|
[layoutManager drawBackgroundForGlyphRange:glyphRange atPoint:textFrame.origin];
|
||||||
[layoutManager drawGlyphsForGlyphRange:glyphRange atPoint:textFrame.origin];
|
[layoutManager drawGlyphsForGlyphRange:glyphRange atPoint:textFrame.origin];
|
||||||
|
|
||||||
@ -170,6 +169,7 @@ static void collectNonTextDescendants(RCTText *view, NSMutableArray *nonTextDesc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#pragma mark - Accessibility
|
#pragma mark - Accessibility
|
||||||
|
|
||||||
- (NSString *)accessibilityLabel
|
- (NSString *)accessibilityLabel
|
||||||
|
@ -76,6 +76,8 @@ RCT_EXPORT_SHADOW_PROPERTY(opacity, CGFloat)
|
|||||||
RCT_EXPORT_SHADOW_PROPERTY(textShadowOffset, CGSize)
|
RCT_EXPORT_SHADOW_PROPERTY(textShadowOffset, CGSize)
|
||||||
RCT_EXPORT_SHADOW_PROPERTY(textShadowRadius, CGFloat)
|
RCT_EXPORT_SHADOW_PROPERTY(textShadowRadius, CGFloat)
|
||||||
RCT_EXPORT_SHADOW_PROPERTY(textShadowColor, UIColor)
|
RCT_EXPORT_SHADOW_PROPERTY(textShadowColor, UIColor)
|
||||||
|
RCT_EXPORT_SHADOW_PROPERTY(adjustsFontSizeToFit, BOOL)
|
||||||
|
RCT_EXPORT_SHADOW_PROPERTY(minimumFontScale, CGFloat)
|
||||||
|
|
||||||
- (RCTViewManagerUIBlock)uiBlockToAmendWithShadowViewRegistry:(NSDictionary<NSNumber *, RCTShadowView *> *)shadowViewRegistry
|
- (RCTViewManagerUIBlock)uiBlockToAmendWithShadowViewRegistry:(NSDictionary<NSNumber *, RCTShadowView *> *)shadowViewRegistry
|
||||||
{
|
{
|
||||||
|
@ -32,6 +32,8 @@ const viewConfig = {
|
|||||||
ellipsizeMode: true,
|
ellipsizeMode: true,
|
||||||
allowFontScaling: true,
|
allowFontScaling: true,
|
||||||
selectable: true,
|
selectable: true,
|
||||||
|
adjustsFontSizeToFit: true,
|
||||||
|
minimumFontScale: true,
|
||||||
}),
|
}),
|
||||||
uiViewClassName: 'RCTText',
|
uiViewClassName: 'RCTText',
|
||||||
};
|
};
|
||||||
@ -166,7 +168,18 @@ const Text = React.createClass({
|
|||||||
* [Accessibility guide](/react-native/docs/accessibility.html#accessible-ios-android)
|
* [Accessibility guide](/react-native/docs/accessibility.html#accessible-ios-android)
|
||||||
* for more information.
|
* for more information.
|
||||||
*/
|
*/
|
||||||
accessible: React.PropTypes.bool,
|
accessible: React.PropTypes.bool,
|
||||||
|
/**
|
||||||
|
* Specifies whether font should be scaled down automatically to fit given style constraints.
|
||||||
|
* @platform ios
|
||||||
|
*/
|
||||||
|
adjustsFontSizeToFit: React.PropTypes.bool,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies smallest possible scale a font can reach when adjustsFontSizeToFit is enabled. (values 0.01-1.0).
|
||||||
|
* @platform ios
|
||||||
|
*/
|
||||||
|
minimumFontScale: React.PropTypes.number,
|
||||||
},
|
},
|
||||||
getDefaultProps(): Object {
|
getDefaultProps(): Object {
|
||||||
return {
|
return {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user