mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-01-12 22:50:10 +08:00
Add support for needsOffscreenAlphaCompositing on iOS (#19052)
Summary: Currently on iOS in UIKit and in RN all views are by default set to `allowsGroupOpacity=true`. Any view that has all of the following - `allowsGroupOpacity` set to true - opacity greater than 0.0 and less than 1.0 - have any subviews will be rendered off screen (on CPU). [See this link for more details](https://stackoverflow.com/questions/13158796/what-triggers-offscreen-rendering-blending-and-layoutsubviews-in-ios/13649143#13649143). Which means performance will be decreased and may affect the user experience. Therefore it makes sense to allow the developers to override this property. This pull request allows for changing `allowsGroupOpacity` via `needsOffscreenAlphaCompositing`. Android already supports this. This is not a new name or variable. See https://facebook.github.io/react-native/docs/view.html#needsoffscreenalphacompositing. Pull Request resolved: https://github.com/facebook/react-native/pull/19052 Differential Revision: D14071300 Pulled By: hramos fbshipit-source-id: 004278801a19463ebf9da6f8855f02ed27926025
This commit is contained in:
committed by
Facebook Github Bot
parent
9101ebdfbb
commit
cf5f25472d
@@ -124,6 +124,33 @@ RCT_CUSTOM_VIEW_PROPERTY(customProp, NSString, RCTPropsTestView)
|
||||
RCT_RUN_RUNLOOP_WHILE(view == nil);
|
||||
}
|
||||
|
||||
- (void)testNeedsOffscreenAlphaCompositing
|
||||
{
|
||||
__block RCTPropsTestView *view;
|
||||
RCTUIManager *uiManager = _bridge.uiManager;
|
||||
|
||||
XCTestExpectation *initialExpectation = [self expectationWithDescription:@"initial expectation"];
|
||||
XCTestExpectation *updateExpectation = [self expectationWithDescription:@"second expectation"];
|
||||
|
||||
dispatch_async(uiManager.methodQueue, ^{
|
||||
[uiManager createView:@2 viewName:@"RCTPropsTestView" rootTag:self->_rootViewReactTag props:@{}];
|
||||
[uiManager addUIBlock:^(__unused RCTUIManager *_uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
|
||||
view = (RCTPropsTestView *)viewRegistry[@2];
|
||||
XCTAssertEqual(view.layer.allowsGroupOpacity, TRUE);
|
||||
[initialExpectation fulfill];
|
||||
}];
|
||||
[uiManager updateView:@2 viewName:@"RCTPropsTestView" props:@{@"needsOffscreenAlphaCompositing": @NO}];
|
||||
[uiManager addUIBlock:^(__unused RCTUIManager *_uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
|
||||
view = (RCTPropsTestView *)viewRegistry[@2];
|
||||
XCTAssertEqual(view.layer.allowsGroupOpacity, FALSE);
|
||||
[updateExpectation fulfill];
|
||||
}];
|
||||
[uiManager setNeedsLayout];
|
||||
});
|
||||
|
||||
[self waitForExpectations:@[initialExpectation, updateExpectation] timeout:0.1];
|
||||
}
|
||||
|
||||
- (void)testResetProps
|
||||
{
|
||||
__block RCTPropsTestView *view;
|
||||
|
||||
@@ -225,6 +225,93 @@ exports.examples = [
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Offscreen Alpha Compositing',
|
||||
render() {
|
||||
type Props = $ReadOnly<{||}>;
|
||||
type State = {|
|
||||
active: boolean,
|
||||
|};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
alphaCompositing: {
|
||||
justifyContent: 'space-around',
|
||||
width: 100,
|
||||
height: 50,
|
||||
borderRadius: 100,
|
||||
},
|
||||
});
|
||||
|
||||
class OffscreenAlphaCompositing extends React.Component<Props, State> {
|
||||
state = {
|
||||
active: false,
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<TouchableWithoutFeedback onPress={this._handlePress}>
|
||||
<View>
|
||||
<Text style={{paddingBottom: 10}}>Blobs</Text>
|
||||
<View
|
||||
style={{opacity: 1.0, paddingBottom: 30}}
|
||||
needsOffscreenAlphaCompositing={this.state.active}>
|
||||
<View
|
||||
style={[
|
||||
styles.alphaCompositing,
|
||||
{marginTop: 0, marginLeft: 0, backgroundColor: '#FF6F59'},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
styles.alphaCompositing,
|
||||
{
|
||||
marginTop: -50,
|
||||
marginLeft: 50,
|
||||
backgroundColor: '#F7CB15',
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</View>
|
||||
<Text style={{paddingBottom: 10}}>
|
||||
Same blobs, but their shared container have 0.5 opacity
|
||||
</Text>
|
||||
<Text style={{paddingBottom: 10}}>
|
||||
Tap to {this.state.active ? 'activate' : 'deactivate'}{' '}
|
||||
needsOffscreenAlphaCompositing
|
||||
</Text>
|
||||
<View
|
||||
style={{opacity: 0.8}}
|
||||
needsOffscreenAlphaCompositing={this.state.active}>
|
||||
<View
|
||||
style={[
|
||||
styles.alphaCompositing,
|
||||
{marginTop: 0, marginLeft: 0, backgroundColor: '#FF6F59'},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
styles.alphaCompositing,
|
||||
{
|
||||
marginTop: -50,
|
||||
marginLeft: 50,
|
||||
backgroundColor: '#F7CB15',
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
</TouchableWithoutFeedback>
|
||||
);
|
||||
}
|
||||
|
||||
_handlePress = () => {
|
||||
this.setState({active: !this.state.active});
|
||||
};
|
||||
}
|
||||
|
||||
return <OffscreenAlphaCompositing />;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'ZIndex',
|
||||
render() {
|
||||
|
||||
@@ -129,6 +129,7 @@ RCT_REMAP_VIEW_PROPERTY(shadowColor, layer.shadowColor, CGColor)
|
||||
RCT_REMAP_VIEW_PROPERTY(shadowOffset, layer.shadowOffset, CGSize)
|
||||
RCT_REMAP_VIEW_PROPERTY(shadowOpacity, layer.shadowOpacity, float)
|
||||
RCT_REMAP_VIEW_PROPERTY(shadowRadius, layer.shadowRadius, CGFloat)
|
||||
RCT_REMAP_VIEW_PROPERTY(needsOffscreenAlphaCompositing, layer.allowsGroupOpacity, BOOL)
|
||||
RCT_CUSTOM_VIEW_PROPERTY(overflow, YGOverflow, RCTView)
|
||||
{
|
||||
if (json) {
|
||||
|
||||
Reference in New Issue
Block a user