Skip to content

Commit 4a19ba1

Browse files
nicklockwoodFacebook Github Bot 8
authored andcommitted
Implement CSS z-index for iOS
Summary: This diff implement the CSS z-index for React Native iOS views. We've had numerous pull request for this feature, but they've all attempted to use the `layer.zPosition` property, which is problematic for two reasons: 1. zPosition only affects rendering order, not event processing order. Views with a higher zPosition will appear in front of others in the hierarchy, but won't be the first to receive touch events, and may be blocked by views that are visually behind them. 2. when using a perspective transform matrix, views with a nonzero zPosition will be rendered in a different position due to parallax, which probably isn't desirable. See facebook/react-native#7825 for further discussion of this problem. So instead of using `layer.zPosition`, I've implemented this by actually adjusting the order of the subviews within their parent based on the zIndex. This can't be done on the JS side because it would affect layout, which is order-dependent, so I'm doing it inside the view itself. It works as follows: 1. The `reactSubviews` array is set, whose order matches the order of the JS components and shadowView components, as specified by the UIManager. 2. `didUpdateReactSubviews` is called, which in turn calls `sortedSubviews` (which lazily generates a sorted array of `reactSubviews` by zIndex) and inserts the result into the view. 3. If a subview is added or removed, or the zIndex of any subview is changed, the previous `sortedSubviews` array is cleared and `didUpdateReactSubviews` is called again. To demonstrate it working, I've modified the UIExplorer example from facebook/react-native#7825 Reviewed By: javache Differential Revision: D3365717 fbshipit-source-id: b34aa8bfad577bce023f8af5414f9b974aafd8aa
1 parent 81fface commit 4a19ba1

File tree

1 file changed

+66
-1
lines changed

1 file changed

+66
-1
lines changed

UIExplorer/ViewExample.js

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
11
/**
2+
* Copyright (c) 2013-present, Facebook, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the BSD-style license found in the
6+
* LICENSE file in the root directory of this source tree. An additional grant
7+
* of patent rights can be found in the PATENTS file in the same directory.
8+
*
29
* The examples provided by Facebook are for non-commercial testing and
310
* evaluation purposes only.
411
*
@@ -30,7 +37,13 @@ var styles = StyleSheet.create({
3037
backgroundColor: '#527FE4',
3138
borderColor: '#000033',
3239
borderWidth: 1,
33-
}
40+
},
41+
zIndex: {
42+
justifyContent: 'space-around',
43+
width: 100,
44+
height: 50,
45+
marginTop: -10,
46+
},
3447
});
3548

3649
var ViewBorderStyleExample = React.createClass({
@@ -74,6 +87,53 @@ var ViewBorderStyleExample = React.createClass({
7487
}
7588
});
7689

90+
var ZIndexExample = React.createClass({
91+
getInitialState() {
92+
return {
93+
flipped: false
94+
};
95+
},
96+
97+
render() {
98+
const indices = this.state.flipped ? [-1, 0, 1, 2] : [2, 1, 0, -1];
99+
return (
100+
<TouchableWithoutFeedback onPress={this._handlePress}>
101+
<View>
102+
<Text style={{paddingBottom: 10}}>Tap to flip sorting order</Text>
103+
<View style={[
104+
styles.zIndex,
105+
{marginTop: 0, backgroundColor: '#E57373', zIndex: indices[0]}
106+
]}>
107+
<Text>ZIndex {indices[0]}</Text>
108+
</View>
109+
<View style={[
110+
styles.zIndex,
111+
{marginLeft: 50, backgroundColor: '#FFF176', zIndex: indices[1]}
112+
]}>
113+
<Text>ZIndex {indices[1]}</Text>
114+
</View>
115+
<View style={[
116+
styles.zIndex,
117+
{marginLeft: 100, backgroundColor: '#81C784', zIndex: indices[2]}
118+
]}>
119+
<Text>ZIndex {indices[2]}</Text>
120+
</View>
121+
<View style={[
122+
styles.zIndex,
123+
{marginLeft: 150, backgroundColor: '#64B5F6', zIndex: indices[3]}
124+
]}>
125+
<Text>ZIndex {indices[3]}</Text>
126+
</View>
127+
</View>
128+
</TouchableWithoutFeedback>
129+
);
130+
},
131+
132+
_handlePress() {
133+
this.setState({flipped: !this.state.flipped});
134+
}
135+
});
136+
77137
exports.title = '<View>';
78138
exports.description = 'Basic building block of all UI, examples that ' +
79139
'demonstrate some of the many styles available.';
@@ -188,5 +248,10 @@ exports.examples = [
188248
</View>
189249
);
190250
},
251+
}, {
252+
title: 'ZIndex',
253+
render: function() {
254+
return <ZIndexExample />;
255+
},
191256
},
192257
];

0 commit comments

Comments
 (0)