Removed RTL workaround in RCTShadowText
Reviewed By: fkgozali Differential Revision: D4511274 fbshipit-source-id: f658afb4e1c943cc9ecab2dd2a91f251edd3fa36
This commit is contained in:
parent
ea6845ca22
commit
7686274e13
Binary file not shown.
Before Width: | Height: | Size: 242 KiB |
|
@ -43,6 +43,8 @@ const {
|
|||
Switch,
|
||||
View,
|
||||
} = ReactNative;
|
||||
const Platform = require('Platform');
|
||||
|
||||
|
||||
const UIExplorerPage = require('./UIExplorerPage');
|
||||
const UIExplorerBlock = require('./UIExplorerBlock');
|
||||
|
@ -100,10 +102,15 @@ function TextAlignmentExample(props) {
|
|||
Left-to-Right language without text alignment.
|
||||
</Text>
|
||||
<Text style={props.style}>
|
||||
{'\u0645\u0646 \u0627\u0644\u064A\u0645\u064A\u0646 \u0625\u0644\u0649 \u0627\u0644\u064A\u0633\u0627\u0631 \u0627\u0644\u0644\u063A\u0629 \u062F\u0648\u0646 \u0645\u062D\u0627\u0630\u0627\u0629 \u0627\u0644\u0646\u0635'}
|
||||
{'\u0645\u0646 \u0627\u0644\u064A\u0645\u064A\u0646 ' +
|
||||
'\u0625\u0644\u0649 \u0627\u0644\u064A\u0633\u0627\u0631 ' +
|
||||
'\u0627\u0644\u0644\u063A\u0629 \u062F\u0648\u0646 ' +
|
||||
'\u0645\u062D\u0627\u0630\u0627\u0629 \u0627\u0644\u0646\u0635'}
|
||||
</Text>
|
||||
<Text style={props.style}>
|
||||
{'\u05DE\u05D9\u05DE\u05D9\u05DF \u05DC\u05E9\u05DE\u05D0\u05DC \u05D4\u05E9\u05E4\u05D4 \u05D1\u05DC\u05D9 \u05D9\u05D9\u05E9\u05D5\u05E8 \u05D8\u05E7\u05E1\u05D8'}
|
||||
{'\u05DE\u05D9\u05DE\u05D9\u05DF \u05DC\u05E9\u05DE\u05D0\u05DC ' +
|
||||
'\u05D4\u05E9\u05E4\u05D4 \u05D1\u05DC\u05D9 ' +
|
||||
'\u05D9\u05D9\u05E9\u05D5\u05E8 \u05D8\u05E7\u05E1\u05D8'}
|
||||
</Text>
|
||||
</View>
|
||||
</UIExplorerBlock>
|
||||
|
@ -157,7 +164,13 @@ class RTLExample extends React.Component {
|
|||
render() {
|
||||
return (
|
||||
<ScrollView
|
||||
style={styles.container}
|
||||
style={[
|
||||
styles.container,
|
||||
// `direction` property is supported only on iOS now.
|
||||
Platform.OS === 'ios' ?
|
||||
{direction: this.state.isRTL ? 'rtl' : 'ltr'} :
|
||||
null
|
||||
]}
|
||||
onLayout={this._onLayout}>
|
||||
<UIExplorerPage title={'Right-to-Left (RTL) UI Layout'}>
|
||||
<UIExplorerBlock title={'Current Layout Direction'}>
|
||||
|
@ -197,14 +210,17 @@ class RTLExample extends React.Component {
|
|||
<TextAlignmentExample
|
||||
title={"Using textAlign: 'left'"}
|
||||
description={
|
||||
'In iOS, you must change active language to flip text alignment correctly.' +
|
||||
'In Android, using forceRTL() flips alignment correctly.'
|
||||
'In iOS/Android, text alignment flips regardless of ' +
|
||||
'languages or text content.'
|
||||
}
|
||||
style={[styles.fontSizeSmall, styles.textAlignLeft]}
|
||||
/>
|
||||
<TextAlignmentExample
|
||||
title={"Using textAlign: 'right'"}
|
||||
description={'In iOS/Android, text alignment flips regardless of languages or text content.'}
|
||||
description={
|
||||
'In iOS/Android, text alignment flips regardless of ' +
|
||||
'languages or text content.'
|
||||
}
|
||||
style={[styles.fontSizeSmall, styles.textAlignRight]}
|
||||
/>
|
||||
<UIExplorerBlock title={'Working With Icons'}>
|
||||
|
@ -235,7 +251,12 @@ class RTLExample extends React.Component {
|
|||
<View Style={styles.view}>
|
||||
<AnimationBlock
|
||||
onPress={this._linearTap}
|
||||
imgStyle={{transform: [{translateX: this.state.linear}, {scaleX: IS_RTL ? -1 : 1}]}}
|
||||
imgStyle={{
|
||||
transform: [
|
||||
{translateX: this.state.linear},
|
||||
{scaleX: IS_RTL ? -1 : 1}
|
||||
]
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
</UIExplorerBlock>
|
||||
|
@ -268,7 +289,8 @@ class RTLExample extends React.Component {
|
|||
},
|
||||
});
|
||||
const offset = IMAGE_SIZE[0] / SCALE / 2 + 10;
|
||||
const toMaxDistance = (IS_RTL ? -1 : 1) * (this.state.windowWidth / 2 - offset);
|
||||
const toMaxDistance =
|
||||
(IS_RTL ? -1 : 1) * (this.state.windowWidth / 2 - offset);
|
||||
Animated.timing(this.state.linear, {
|
||||
toValue: this.state.toggleStatus[refName] ? toMaxDistance : 0,
|
||||
duration: 2000,
|
||||
|
|
|
@ -150,7 +150,6 @@ var styles = StyleSheet.create({
|
|||
fontSize: 16,
|
||||
fontWeight: 'bold',
|
||||
margin: 5,
|
||||
textAlign: 'left',
|
||||
},
|
||||
button: {
|
||||
margin: 5,
|
||||
|
|
|
@ -37,6 +37,7 @@ CGFloat const RCTTextAutoSizeGranularity = 0.001f;
|
|||
CGFloat _cachedTextStorageWidthMode;
|
||||
NSAttributedString *_cachedAttributedString;
|
||||
CGFloat _effectiveLetterSpacing;
|
||||
UIUserInterfaceLayoutDirection _cachedEffectiveLayoutDirection;
|
||||
}
|
||||
|
||||
static YGSize RCTMeasure(YGNodeRef node, float width, YGMeasureMode widthMode, float height, YGMeasureMode heightMode)
|
||||
|
@ -68,7 +69,12 @@ static YGSize RCTMeasure(YGNodeRef node, float width, YGMeasureMode widthMode, f
|
|||
_cachedTextStorageWidth = -1;
|
||||
_cachedTextStorageWidthMode = -1;
|
||||
_fontSizeMultiplier = 1.0;
|
||||
_textAlign = NSTextAlignmentNatural;
|
||||
_writingDirection = NSWritingDirectionNatural;
|
||||
_cachedEffectiveLayoutDirection = UIUserInterfaceLayoutDirectionLeftToRight;
|
||||
|
||||
YGNodeSetMeasureFunc(self.cssNode, RCTMeasure);
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(contentSizeMultiplierDidChange:)
|
||||
name:RCTUIManagerWillUpdateViewsDueToContentSizeMultiplierChangeNotification
|
||||
|
@ -189,7 +195,12 @@ static YGSize RCTMeasure(YGNodeRef node, float width, YGMeasureMode widthMode, f
|
|||
|
||||
- (NSTextStorage *)buildTextStorageForWidth:(CGFloat)width widthMode:(YGMeasureMode)widthMode
|
||||
{
|
||||
if (_cachedTextStorage && width == _cachedTextStorageWidth && widthMode == _cachedTextStorageWidthMode) {
|
||||
if (
|
||||
_cachedTextStorage &&
|
||||
width == _cachedTextStorageWidth &&
|
||||
widthMode == _cachedTextStorageWidthMode &&
|
||||
_cachedEffectiveLayoutDirection == self.effectiveLayoutDirection
|
||||
) {
|
||||
return _cachedTextStorage;
|
||||
}
|
||||
|
||||
|
@ -256,10 +267,16 @@ static YGSize RCTMeasure(YGNodeRef node, float width, YGMeasureMode widthMode, f
|
|||
backgroundColor:(UIColor *)backgroundColor
|
||||
opacity:(CGFloat)opacity
|
||||
{
|
||||
if (![self isTextDirty] && _cachedAttributedString) {
|
||||
if (
|
||||
![self isTextDirty] &&
|
||||
_cachedAttributedString &&
|
||||
_cachedEffectiveLayoutDirection == self.effectiveLayoutDirection
|
||||
) {
|
||||
return _cachedAttributedString;
|
||||
}
|
||||
|
||||
_cachedEffectiveLayoutDirection = self.effectiveLayoutDirection;
|
||||
|
||||
if (_fontSize && !isnan(_fontSize)) {
|
||||
fontSize = @(_fontSize);
|
||||
}
|
||||
|
@ -367,80 +384,61 @@ static YGSize RCTMeasure(YGNodeRef node, float width, YGMeasureMode widthMode, f
|
|||
* varying lineHeights, we simply take the max.
|
||||
*/
|
||||
- (void)_setParagraphStyleOnAttributedString:(NSMutableAttributedString *)attributedString
|
||||
fontLineHeight:(CGFloat)fontLineHeight
|
||||
fontLineHeight:(CGFloat)fontLineHeight
|
||||
heightOfTallestSubview:(CGFloat)heightOfTallestSubview
|
||||
{
|
||||
// check if we have lineHeight set on self
|
||||
__block BOOL hasParagraphStyle = NO;
|
||||
if (_lineHeight || _textAlign) {
|
||||
|
||||
if (_lineHeight != 0.0 || _textAlign != NSTextAlignmentNatural) {
|
||||
hasParagraphStyle = YES;
|
||||
}
|
||||
|
||||
__block float newLineHeight = _lineHeight ?: 0.0;
|
||||
|
||||
CGFloat fontSizeMultiplier = _allowFontScaling ? _fontSizeMultiplier : 1.0;
|
||||
|
||||
// check for lineHeight on each of our children, update the max as we go (in self.lineHeight)
|
||||
[attributedString enumerateAttribute:NSParagraphStyleAttributeName inRange:(NSRange){0, attributedString.length} options:0 usingBlock:^(id value, NSRange range, BOOL *stop) {
|
||||
if (value) {
|
||||
NSParagraphStyle *paragraphStyle = (NSParagraphStyle *)value;
|
||||
CGFloat maximumLineHeight = round(paragraphStyle.maximumLineHeight / fontSizeMultiplier);
|
||||
if (maximumLineHeight > newLineHeight) {
|
||||
newLineHeight = maximumLineHeight;
|
||||
}
|
||||
hasParagraphStyle = YES;
|
||||
// Text line height
|
||||
__block float compoundLineHeight = _lineHeight * fontSizeMultiplier;
|
||||
|
||||
// Checking for `maximumLineHeight` on each of our children and updating `compoundLineHeight` with the maximum value on the go.
|
||||
[attributedString enumerateAttribute:NSParagraphStyleAttributeName
|
||||
inRange:(NSRange){0, attributedString.length}
|
||||
options:0
|
||||
usingBlock:^(NSParagraphStyle *paragraphStyle, NSRange range, BOOL *stop) {
|
||||
|
||||
if (!paragraphStyle) {
|
||||
return;
|
||||
}
|
||||
|
||||
hasParagraphStyle = YES;
|
||||
compoundLineHeight = MAX(compoundLineHeight, paragraphStyle.maximumLineHeight);
|
||||
}];
|
||||
|
||||
if (self.lineHeight != newLineHeight) {
|
||||
self.lineHeight = newLineHeight;
|
||||
}
|
||||
compoundLineHeight = MAX(round(compoundLineHeight), ceilf(heightOfTallestSubview));
|
||||
|
||||
NSTextAlignment newTextAlign = _textAlign ?: NSTextAlignmentNatural;
|
||||
|
||||
// The part below is to address textAlign for RTL language before setting paragraph style
|
||||
// Since we can't get layout directly because this logic is currently run just before layout is calculatede
|
||||
// We will climb up to the first node which style has been setted as non-inherit
|
||||
if (newTextAlign == NSTextAlignmentRight || newTextAlign == NSTextAlignmentLeft) {
|
||||
RCTShadowView *view = self;
|
||||
while (view != nil && YGNodeStyleGetDirection(view.cssNode) == YGDirectionInherit) {
|
||||
view = [view reactSuperview];
|
||||
}
|
||||
if (view != nil && YGNodeStyleGetDirection(view.cssNode) == YGDirectionRTL) {
|
||||
if (newTextAlign == NSTextAlignmentRight) {
|
||||
newTextAlign = NSTextAlignmentLeft;
|
||||
} else if (newTextAlign == NSTextAlignmentLeft) {
|
||||
newTextAlign = NSTextAlignmentRight;
|
||||
// Text alignment
|
||||
NSTextAlignment textAlign = _textAlign;
|
||||
if (textAlign == NSTextAlignmentRight || textAlign == NSTextAlignmentLeft) {
|
||||
if (_cachedEffectiveLayoutDirection == UIUserInterfaceLayoutDirectionRightToLeft) {
|
||||
if (textAlign == NSTextAlignmentRight) {
|
||||
textAlign = NSTextAlignmentLeft;
|
||||
} else {
|
||||
textAlign = NSTextAlignmentRight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (self.textAlign != newTextAlign) {
|
||||
self.textAlign = newTextAlign;
|
||||
}
|
||||
NSWritingDirection newWritingDirection = _writingDirection ?: NSWritingDirectionNatural;
|
||||
if (self.writingDirection != newWritingDirection) {
|
||||
self.writingDirection = newWritingDirection;
|
||||
}
|
||||
|
||||
// if we found anything, set it :D
|
||||
if (hasParagraphStyle) {
|
||||
NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new];
|
||||
paragraphStyle.alignment = _textAlign;
|
||||
paragraphStyle.alignment = textAlign;
|
||||
paragraphStyle.baseWritingDirection = _writingDirection;
|
||||
CGFloat lineHeight = round(_lineHeight * fontSizeMultiplier);
|
||||
if (heightOfTallestSubview > lineHeight) {
|
||||
lineHeight = ceilf(heightOfTallestSubview);
|
||||
}
|
||||
paragraphStyle.minimumLineHeight = lineHeight;
|
||||
paragraphStyle.maximumLineHeight = lineHeight;
|
||||
paragraphStyle.minimumLineHeight = compoundLineHeight;
|
||||
paragraphStyle.maximumLineHeight = compoundLineHeight;
|
||||
[attributedString addAttribute:NSParagraphStyleAttributeName
|
||||
value:paragraphStyle
|
||||
range:(NSRange){0, attributedString.length}];
|
||||
|
||||
if (lineHeight > fontLineHeight) {
|
||||
if (compoundLineHeight > fontLineHeight) {
|
||||
[attributedString addAttribute:NSBaselineOffsetAttributeName
|
||||
value:@(lineHeight / 2 - fontLineHeight / 2)
|
||||
value:@(compoundLineHeight / 2 - fontLineHeight / 2)
|
||||
range:(NSRange){0, attributedString.length}];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -441,6 +441,8 @@ static void RCTProcessMetaPropsBorder(const YGValue metaProps[META_PROP_COUNT],
|
|||
// Layout Direction
|
||||
|
||||
- (UIUserInterfaceLayoutDirection)effectiveLayoutDirection {
|
||||
// Even if `YGNodeLayoutGetDirection` can return `YGDirectionInherit` here, it actually means
|
||||
// that Yoga will use LTR layout for the view (even if layout process is not finished yet).
|
||||
return YGNodeLayoutGetDirection(self.cssNode) == YGDirectionRTL ? UIUserInterfaceLayoutDirectionRightToLeft : UIUserInterfaceLayoutDirectionLeftToRight;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue