Re-render views when direction changes

Reviewed By: shergin

Differential Revision: D5959573

fbshipit-source-id: 36b2cde921362a934a2c88a3ed05be5082ed08bf
This commit is contained in:
Ramanpreet Nara 2017-10-03 12:54:50 -07:00 committed by Facebook Github Bot
parent bbcfcdb8ed
commit 992ade1fc5
6 changed files with 626 additions and 450 deletions

View File

@ -38,7 +38,7 @@ static CGFloat const kAutoSizeGranularity = 0.001f;
CGFloat _cachedTextStorageWidthMode;
NSAttributedString *_cachedAttributedString;
CGFloat _effectiveLetterSpacing;
UIUserInterfaceLayoutDirection _cachedEffectiveLayoutDirection;
UIUserInterfaceLayoutDirection _cachedLayoutDirection;
}
static YGSize RCTMeasure(YGNodeRef node, float width, YGMeasureMode widthMode, float height, YGMeasureMode heightMode)
@ -72,7 +72,7 @@ static YGSize RCTMeasure(YGNodeRef node, float width, YGMeasureMode widthMode, f
_fontSizeMultiplier = 1.0;
_textAlign = NSTextAlignmentNatural;
_writingDirection = NSWritingDirectionNatural;
_cachedEffectiveLayoutDirection = UIUserInterfaceLayoutDirectionLeftToRight;
_cachedLayoutDirection = UIUserInterfaceLayoutDirectionLeftToRight;
YGNodeSetMeasureFunc(self.yogaNode, RCTMeasure);
@ -198,7 +198,7 @@ static YGSize RCTMeasure(YGNodeRef node, float width, YGMeasureMode widthMode, f
_cachedTextStorage &&
(width == _cachedTextStorageWidth || (isnan(width) && isnan(_cachedTextStorageWidth))) &&
widthMode == _cachedTextStorageWidthMode &&
_cachedEffectiveLayoutDirection == self.effectiveLayoutDirection
_cachedLayoutDirection == self.layoutDirection
) {
return _cachedTextStorage;
}
@ -272,12 +272,12 @@ static YGSize RCTMeasure(YGNodeRef node, float width, YGMeasureMode widthMode, f
if (
![self isTextDirty] &&
_cachedAttributedString &&
_cachedEffectiveLayoutDirection == self.effectiveLayoutDirection
_cachedLayoutDirection == self.layoutDirection
) {
return _cachedAttributedString;
}
_cachedEffectiveLayoutDirection = self.effectiveLayoutDirection;
_cachedLayoutDirection = self.layoutDirection;
if (_fontSize && !isnan(_fontSize)) {
fontSize = @(_fontSize);
@ -419,7 +419,7 @@ static YGSize RCTMeasure(YGNodeRef node, float width, YGMeasureMode widthMode, f
// Text alignment
NSTextAlignment textAlign = _textAlign;
if (textAlign == NSTextAlignmentRight || textAlign == NSTextAlignmentLeft) {
if (_cachedEffectiveLayoutDirection == UIUserInterfaceLayoutDirectionRightToLeft) {
if (_cachedLayoutDirection == UIUserInterfaceLayoutDirectionRightToLeft) {
if (textAlign == NSTextAlignmentRight) {
textAlign = NSTextAlignmentLeft;
} else {

View File

@ -15,13 +15,56 @@ const Platform = require('Platform');
var React = require('react');
var createReactClass = require('create-react-class');
var ReactNative = require('react-native');
var {
Image,
StyleSheet,
Text,
View,
LayoutAnimation,
} = ReactNative;
var {Image, Text, View, LayoutAnimation, Button} = ReactNative;
type TextAlignExampleRTLState = {|
isRTL: boolean,
|};
class TextAlignRTLExample extends React.Component<*, TextAlignExampleRTLState> {
constructor(...args: Array<*>) {
super(...args);
this.state = {
isRTL: false,
};
}
render() {
const {isRTL} = this.state;
const toggleRTL = () => this.setState({isRTL: !isRTL});
return (
<View style={{direction: isRTL ? 'rtl' : 'ltr'}}>
<Text>auto (default) - english LTR</Text>
<Text>
{'\u0623\u062D\u0628 \u0627\u0644\u0644\u063A\u0629 ' +
'\u0627\u0644\u0639\u0631\u0628\u064A\u0629 auto (default) - arabic RTL'}
</Text>
<Text style={{textAlign: 'left'}}>
left left left left left left left left left left left left left left
left
</Text>
<Text style={{textAlign: 'center'}}>
center center center center center center center center center center
center
</Text>
<Text style={{textAlign: 'right'}}>
right right right right right right right right right right right
right right
</Text>
<Text style={{textAlign: 'justify'}}>
justify: this text component{"'"}s contents are laid out with
"textAlign: justify" and as you can see all of the lines except the
last one span the available width of the parent container.
</Text>
<Button
onPress={toggleRTL}
title={`Switch to ${isRTL ? 'LTR' : 'RTL'}`}
/>
</View>
);
}
}
class Entity extends React.Component<$FlowFixMeProps> {
render() {
@ -38,25 +81,31 @@ class AttributeToggler extends React.Component<{}, $FlowFixMeState> {
toggleWeight = () => {
this.setState({
fontWeight: this.state.fontWeight === 'bold' ? 'normal' : 'bold'
fontWeight: this.state.fontWeight === 'bold' ? 'normal' : 'bold',
});
};
increaseSize = () => {
this.setState({
fontSize: this.state.fontSize + 1
fontSize: this.state.fontSize + 1,
});
};
render() {
var curStyle = {fontWeight: this.state.fontWeight, fontSize: this.state.fontSize};
var curStyle = {
fontWeight: this.state.fontWeight,
fontSize: this.state.fontSize,
};
return (
<View>
<Text style={curStyle}>
Tap the controls below to change attributes.
</Text>
<Text>
<Text>See how it will even work on <Text style={curStyle}>this nested text</Text></Text>
<Text>
See how it will even work on{' '}
<Text style={curStyle}>this nested text</Text>
</Text>
</Text>
<Text
style={{backgroundColor: '#ffaaaa', marginTop: 5}}
@ -76,7 +125,7 @@ class AttributeToggler extends React.Component<{}, $FlowFixMeState> {
var AdjustingFontSize = createReactClass({
displayName: 'AdjustingFontSize',
getInitialState: function() {
return {dynamicText:'', shouldRender: true,};
return {dynamicText: '', shouldRender: true};
},
reset: function() {
LayoutAnimation.easeInEaseOut();
@ -93,37 +142,58 @@ var AdjustingFontSize = createReactClass({
},
addText: function() {
this.setState({
dynamicText: this.state.dynamicText + (Math.floor((Math.random() * 10) % 2) ? ' foo' : ' bar'),
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),
dynamicText: this.state.dynamicText.slice(
0,
this.state.dynamicText.length - 4,
),
});
},
render: function() {
if (!this.state.shouldRender) {
return (<View/>);
return <View />;
}
return (
<View>
<Text ellipsizeMode="tail" numberOfLines={1} style={{fontSize: 36, marginVertical: 6}}>
<Text
ellipsizeMode="tail"
numberOfLines={1}
style={{fontSize: 36, marginVertical: 6}}>
Truncated text is baaaaad.
</Text>
<Text numberOfLines={1} adjustsFontSizeToFit={true} style={{fontSize: 40, marginVertical:6}}>
<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}}>
<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
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
adjustsFontSizeToFit={true}
numberOfLines={1}
style={{marginVertical: 6}}>
<Text style={{fontSize: 14}}>
{'Differently sized nested elements will shrink together. '}
</Text>
@ -132,26 +202,26 @@ var AdjustingFontSize = createReactClass({
</Text>
</Text>
<View style={{flexDirection:'row', justifyContent:'space-around', marginTop: 5, marginVertical:6}}>
<Text
style={{backgroundColor: '#ffaaaa'}}
onPress={this.reset}>
<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}>
<Text style={{backgroundColor: '#aaaaff'}} onPress={this.removeText}>
Remove Text
</Text>
<Text
style={{backgroundColor: '#aaffaa'}}
onPress={this.addText}>
<Text style={{backgroundColor: '#aaffaa'}} onPress={this.addText}>
Add Text
</Text>
</View>
</View>
);
}
},
});
exports.title = '<Text>';
@ -163,12 +233,13 @@ exports.examples = [
render: function() {
return (
<Text>
The text should wrap if it goes on multiple lines. See, this is going to
the next line.
The text should wrap if it goes on multiple lines. See, this is going
to the next line.
</Text>
);
},
}, {
},
{
title: 'Padding',
render: function() {
return (
@ -177,61 +248,63 @@ exports.examples = [
</Text>
);
},
}, {
},
{
title: 'Font Family',
render: function() {
return (
<View>
<Text style={{fontFamily: (Platform.isTVOS ? 'Times' : 'Cochin')}}>
<Text style={{fontFamily: Platform.isTVOS ? 'Times' : 'Cochin'}}>
Cochin
</Text>
<Text style={{fontFamily: (Platform.isTVOS ? 'Times' : 'Cochin'), fontWeight: 'bold'}}>
<Text
style={{
fontFamily: Platform.isTVOS ? 'Times' : 'Cochin',
fontWeight: 'bold',
}}>
Cochin bold
</Text>
<Text style={{fontFamily: 'Helvetica'}}>
Helvetica
</Text>
<Text style={{fontFamily: 'Helvetica'}}>Helvetica</Text>
<Text style={{fontFamily: 'Helvetica', fontWeight: 'bold'}}>
Helvetica bold
</Text>
<Text style={{fontFamily: (Platform.isTVOS ? 'Courier' : 'Verdana')}}>
<Text style={{fontFamily: Platform.isTVOS ? 'Courier' : 'Verdana'}}>
Verdana
</Text>
<Text style={{fontFamily: (Platform.isTVOS ? 'Courier' : 'Verdana'), fontWeight: 'bold'}}>
<Text
style={{
fontFamily: Platform.isTVOS ? 'Courier' : 'Verdana',
fontWeight: 'bold',
}}>
Verdana bold
</Text>
</View>
);
},
}, {
},
{
title: 'Font Size',
render: function() {
return (
<View>
<Text style={{fontSize: 23}}>
Size 23
</Text>
<Text style={{fontSize: 8}}>
Size 8
</Text>
<Text style={{fontSize: 23}}>Size 23</Text>
<Text style={{fontSize: 8}}>Size 8</Text>
</View>
);
},
}, {
},
{
title: 'Color',
render: function() {
return (
<View>
<Text style={{color: 'red'}}>
Red color
</Text>
<Text style={{color: 'blue'}}>
Blue color
</Text>
<Text style={{color: 'red'}}>Red color</Text>
<Text style={{color: 'blue'}}>Blue color</Text>
</View>
);
},
}, {
},
{
title: 'Font Weight',
render: function() {
return (
@ -254,61 +327,97 @@ exports.examples = [
</View>
);
},
}, {
},
{
title: 'Font Style',
render: function() {
return (
<View>
<Text style={{fontStyle: 'normal'}}>
Normal text
</Text>
<Text style={{fontStyle: 'italic'}}>
Italic text
</Text>
<Text style={{fontStyle: 'normal'}}>Normal text</Text>
<Text style={{fontStyle: 'italic'}}>Italic text</Text>
</View>
);
},
}, {
},
{
title: 'Selectable',
render: function() {
return (
<View>
<Text selectable={true}>
This text is <Text style={{fontWeight: 'bold'}}>selectable</Text> if you click-and-hold.
This text is <Text style={{fontWeight: 'bold'}}>selectable</Text> if
you click-and-hold.
</Text>
</View>
);
},
}, {
},
{
title: 'Text Decoration',
render: function() {
return (
<View>
<Text style={{textDecorationLine: 'underline', textDecorationStyle: 'solid'}}>
<Text
style={{
textDecorationLine: 'underline',
textDecorationStyle: 'solid',
}}>
Solid underline
</Text>
<Text style={{textDecorationLine: 'underline', textDecorationStyle: 'double', textDecorationColor: '#ff0000'}}>
<Text
style={{
textDecorationLine: 'underline',
textDecorationStyle: 'double',
textDecorationColor: '#ff0000',
}}>
Double underline with custom color
</Text>
<Text style={{textDecorationLine: 'underline', textDecorationStyle: 'dashed', textDecorationColor: '#9CDC40'}}>
<Text
style={{
textDecorationLine: 'underline',
textDecorationStyle: 'dashed',
textDecorationColor: '#9CDC40',
}}>
Dashed underline with custom color
</Text>
<Text style={{textDecorationLine: 'underline', textDecorationStyle: 'dotted', textDecorationColor: 'blue'}}>
<Text
style={{
textDecorationLine: 'underline',
textDecorationStyle: 'dotted',
textDecorationColor: 'blue',
}}>
Dotted underline with custom color
</Text>
<Text style={{textDecorationLine: 'none'}}>
None textDecoration
</Text>
<Text style={{textDecorationLine: 'line-through', textDecorationStyle: 'solid'}}>
<Text style={{textDecorationLine: 'none'}}>None textDecoration</Text>
<Text
style={{
textDecorationLine: 'line-through',
textDecorationStyle: 'solid',
}}>
Solid line-through
</Text>
<Text style={{textDecorationLine: 'line-through', textDecorationStyle: 'double', textDecorationColor: '#ff0000'}}>
<Text
style={{
textDecorationLine: 'line-through',
textDecorationStyle: 'double',
textDecorationColor: '#ff0000',
}}>
Double line-through with custom color
</Text>
<Text style={{textDecorationLine: 'line-through', textDecorationStyle: 'dashed', textDecorationColor: '#9CDC40'}}>
<Text
style={{
textDecorationLine: 'line-through',
textDecorationStyle: 'dashed',
textDecorationColor: '#9CDC40',
}}>
Dashed line-through with custom color
</Text>
<Text style={{textDecorationLine: 'line-through', textDecorationStyle: 'dotted', textDecorationColor: 'blue'}}>
<Text
style={{
textDecorationLine: 'line-through',
textDecorationStyle: 'dotted',
textDecorationColor: 'blue',
}}>
Dotted line-through with custom color
</Text>
<Text style={{textDecorationLine: 'underline line-through'}}>
@ -317,9 +426,11 @@ exports.examples = [
</View>
);
},
}, {
},
{
title: 'Nested',
description: 'Nested text components will inherit the styles of their ' +
description:
'Nested text components will inherit the styles of their ' +
'parents (only backgroundColor is inherited from non-Text parents). ' +
'<Text> only supports other <Text> and raw text (strings) as children.',
render: function() {
@ -357,42 +468,45 @@ exports.examples = [
</View>
);
},
}, {
},
{
title: 'Text Align',
render: function() {
return (
<View>
<Text>auto (default) - english LTR</Text>
<Text>
auto (default) - english LTR
</Text>
<Text>
أحب اللغة العربية auto (default) - arabic RTL
{'\u0623\u062D\u0628 \u0627\u0644\u0644\u063A\u0629 ' +
'\u0627\u0644\u0639\u0631\u0628\u064A\u0629 auto (default) - arabic ' +
'RTL'}
</Text>
<Text style={{textAlign: 'left'}}>
left left left left left left left left left left left left left left left
left left left left left left left left left left left left left
left left
</Text>
<Text style={{textAlign: 'center'}}>
center center center center center center center center center center center
center center center center center center center center center
center center
</Text>
<Text style={{textAlign: 'right'}}>
right right right right right right right right right right right right right
right right right right right right right right right right right
right right
</Text>
<Text style={{textAlign: 'justify'}}>
justify: this text component{"'"}s contents are laid out with "textAlign: justify"
and as you can see all of the lines except the last one span the
available width of the parent container.
justify: this text component{"'"}s contents are laid out with
"textAlign: justify" and as you can see all of the lines except the
last one span the available width of the parent container.
</Text>
</View>
);
},
}, {
},
{
title: 'Letter Spacing',
render: function() {
return (
<View>
<Text style={{letterSpacing: 0}}>
letterSpacing = 0
</Text>
<Text style={{letterSpacing: 0}}>letterSpacing = 0</Text>
<Text style={{letterSpacing: 2, marginTop: 5}}>
letterSpacing = 2
</Text>
@ -405,7 +519,8 @@ exports.examples = [
</View>
);
},
}, {
},
{
title: 'Spaces',
render: function() {
return (
@ -414,7 +529,8 @@ exports.examples = [
</Text>
);
},
}, {
},
{
title: 'Line Height',
render: function() {
return (
@ -426,20 +542,21 @@ exports.examples = [
</Text>
);
},
}, {
title: 'Empty Text',
description: 'It\'s ok to have Text with zero or null children.',
render: function() {
return (
<Text />
);
},
}, {
{
title: 'Empty Text',
description: "It's ok to have Text with zero or null children.",
render: function() {
return <Text />;
},
},
{
title: 'Toggling Attributes',
render: function(): React.Element<any> {
return <AttributeToggler />;
},
}, {
},
{
title: 'backgroundColor attribute',
description: 'backgroundColor is inherited from all types of views.',
render: function() {
@ -447,13 +564,17 @@ exports.examples = [
<Text style={{backgroundColor: 'yellow'}}>
Yellow container background,
<Text style={{backgroundColor: '#ffaaaa'}}>
{' '}red background,
{' '}
red background,
<Text style={{backgroundColor: '#aaaaff'}}>
{' '}blue background,
{' '}
blue background,
<Text>
{' '}inherited blue background,
{' '}
inherited blue background,
<Text style={{backgroundColor: '#aaffaa'}}>
{' '}nested green background.
{' '}
nested green background.
</Text>
</Text>
</Text>
@ -461,44 +582,70 @@ exports.examples = [
</Text>
);
},
}, {
},
{
title: 'numberOfLines attribute',
render: function() {
return (
<View>
<Text numberOfLines={1}>
Maximum of one line, no matter how much I write here. If I keep writing, it{"'"}ll just truncate after one line.
Maximum of one line, no matter how much I write here. If I keep
writing, it{"'"}ll just truncate after one line.
</Text>
<Text numberOfLines={2} style={{marginTop: 20}}>
Maximum of two lines, no matter how much I write here. If I keep writing, it{"'"}ll just truncate after two lines.
Maximum of two lines, no matter how much I write here. If I keep
writing, it{"'"}ll just truncate after two lines.
</Text>
<Text style={{marginTop: 20}}>
No maximum lines specified, no matter how much I write here. If I keep writing, it{"'"}ll just keep going and going.
No maximum lines specified, no matter how much I write here. If I
keep writing, it{"'"}ll just keep going and going.
</Text>
</View>
);
},
}, {
},
{
title: 'Text highlighting (tap the link to see highlight)',
render: function() {
return (
<View>
<Text>Lorem ipsum dolor sit amet, <Text suppressHighlighting={false} style={{backgroundColor: 'white', textDecorationLine: 'underline', color: 'blue'}} onPress={() => null}>consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud</Text> exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</Text>
<Text>
Lorem ipsum dolor sit amet,{' '}
<Text
suppressHighlighting={false}
style={{
backgroundColor: 'white',
textDecorationLine: 'underline',
color: 'blue',
}}
onPress={() => null}>
consectetur adipiscing elit, sed do eiusmod tempor incididunt ut
labore et dolore magna aliqua. Ut enim ad minim veniam, quis
nostrud
</Text>{' '}
exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat.
</Text>
</View>
);
},
}, {
},
{
title: 'allowFontScaling attribute',
render: function() {
return (
<View>
<Text>
By default, text will respect Text Size accessibility setting on iOS.
It means that all font sizes will be increased or descreased depending on the value of Text Size setting in
{" "}<Text style={{fontWeight: 'bold'}}>Settings.app - Display & Brightness - Text Size</Text>
By default, text will respect Text Size accessibility setting on
iOS. It means that all font sizes will be increased or descreased
depending on the value of Text Size setting in{' '}
<Text style={{fontWeight: 'bold'}}>
Settings.app - Display & Brightness - Text Size
</Text>
</Text>
<Text style={{marginTop: 10}}>
You can disable scaling for your Text component by passing {"\""}allowFontScaling={"{"}false{"}\""} prop.
You can disable scaling for your Text component by passing {'"'}allowFontScaling={'{'}false{'}"'}{' '}
prop.
</Text>
<Text allowFontScaling={false} style={{marginTop: 20}}>
This text will not scale.
@ -506,30 +653,46 @@ exports.examples = [
</View>
);
},
}, {
},
{
title: 'Inline views',
render: function() {
return (
<View>
<Text>
This text contains an inline blue view <View style={{width: 25, height: 25, backgroundColor: 'steelblue'}} /> and
an inline image <Image source={require('./flux.png')} style={{width: 30, height: 11, resizeMode: 'cover'}}/>. Neat, huh?
This text contains an inline blue view{' '}
<View
style={{width: 25, height: 25, backgroundColor: 'steelblue'}}
/>{' '}
and an inline image{' '}
<Image
source={require('./flux.png')}
style={{width: 30, height: 11, resizeMode: 'cover'}}
/>. Neat, huh?
</Text>
</View>
);
},
}, {
},
{
title: 'Text shadow',
render: function() {
return (
<View>
<Text style={{fontSize: 20, textShadowOffset: {width: 2, height: 2}, textShadowRadius: 1, textShadowColor: '#00cccc'}}>
<Text
style={{
fontSize: 20,
textShadowOffset: {width: 2, height: 2},
textShadowRadius: 1,
textShadowColor: '#00cccc',
}}>
Demo text shadow
</Text>
</View>
);
},
}, {
},
{
title: 'Ellipsize mode',
render: function() {
return (
@ -549,18 +712,25 @@ exports.examples = [
</View>
);
},
}, {
},
{
title: 'Font variants',
render: function() {
return (
<View>
<Text style={{fontVariant: ['small-caps']}}>
Small Caps{'\n'}
</Text>
<Text style={{fontFamily: (Platform.isTVOS ? 'Times' : 'Hoefler Text'), fontVariant: ['oldstyle-nums']}}>
<Text style={{fontVariant: ['small-caps']}}>Small Caps{'\n'}</Text>
<Text
style={{
fontFamily: Platform.isTVOS ? 'Times' : 'Hoefler Text',
fontVariant: ['oldstyle-nums'],
}}>
Old Style nums 0123456789{'\n'}
</Text>
<Text style={{fontFamily: (Platform.isTVOS ? 'Times' : 'Hoefler Text'), fontVariant: ['lining-nums']}}>
<Text
style={{
fontFamily: Platform.isTVOS ? 'Times' : 'Hoefler Text',
fontVariant: ['lining-nums'],
}}>
Lining nums 0123456789{'\n'}
</Text>
<Text style={{fontVariant: ['tabular-nums']}}>
@ -576,9 +746,17 @@ exports.examples = [
</View>
);
},
}, {
},
{
title: 'Dynamic Font Size Adjustment',
render: function(): React.Element<any> {
return <AdjustingFontSize />;
},
}];
},
{
title: 'Text Align with RTL',
render: function() {
return <TextAlignRTLExample />;
},
},
];

View File

@ -497,7 +497,7 @@ static NSDictionary *deviceOrientationEventBody(UIDeviceOrientation orientation)
reactTags[index] = shadowView.reactTag;
frameDataArray[index++] = (RCTFrameData){
shadowView.frame,
shadowView.effectiveLayoutDirection,
shadowView.layoutDirection,
shadowView.isNewView,
shadowView.superview.isNewView,
shadowView.isHidden,

View File

@ -27,7 +27,7 @@
absolutePosition:(CGPoint)absolutePosition
{
// Call super method if LTR layout is enforced.
if (self.effectiveLayoutDirection == UIUserInterfaceLayoutDirectionLeftToRight) {
if (YGNodeLayoutGetDirection(self.yogaNode) != YGDirectionRTL) {
[super applyLayoutNode:node
viewsWithNewFrame:viewsWithNewFrame
absolutePosition:absolutePosition];

View File

@ -84,9 +84,10 @@ typedef void (^RCTApplierBlock)(NSDictionary<NSNumber *, UIView *> *viewRegistry
@property (nonatomic, assign, getter=isHidden) BOOL hidden;
/**
* Computed layout direction for the view backed to Yoga node value.
* Computed layout direction of the view.
*/
@property (nonatomic, assign, readonly) UIUserInterfaceLayoutDirection effectiveLayoutDirection;
@property (nonatomic, assign, readonly) UIUserInterfaceLayoutDirection layoutDirection;
/**
* Position and dimensions.

View File

@ -204,8 +204,13 @@ static void RCTProcessMetaPropsBorder(const YGValue metaProps[META_PROP_COUNT],
RCTRoundPixelValue(absoluteBottomRight.y - absoluteTopLeft.y)
}};
if (!CGRectEqualToRect(frame, _frame)) {
// 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).
UIUserInterfaceLayoutDirection updatedLayoutDirection = YGNodeLayoutGetDirection(_yogaNode) == YGDirectionRTL ? UIUserInterfaceLayoutDirectionRightToLeft : UIUserInterfaceLayoutDirectionLeftToRight;
if (!CGRectEqualToRect(frame, _frame) || _layoutDirection != updatedLayoutDirection) {
_frame = frame;
_layoutDirection = updatedLayoutDirection;
[viewsWithNewFrame addObject:self];
}
@ -491,14 +496,6 @@ static void RCTProcessMetaPropsBorder(const YGValue metaProps[META_PROP_COUNT],
return description;
}
// 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(_yogaNode) == YGDirectionRTL ? UIUserInterfaceLayoutDirectionRightToLeft : UIUserInterfaceLayoutDirectionLeftToRight;
}
// Margin
#define RCT_MARGIN_PROPERTY(prop, metaProp) \