Fixed text background color

Summary:
@public

This fixes an issue with the containerBackgroundColor property of `<Text>` nodes, where containerBackgroundColor was being overridden by the backgroundColor. I also fixed up the example so that it demonstrates the feature more clearly.

Test Plan:
* Check UIExplorer text example
* Run Catalyst snapshot tests and check MAdMan, Groups
This commit is contained in:
Nick Lockwood 2015-05-28 09:29:27 -07:00
parent 656c5e4e27
commit 45c1dc1c65
11 changed files with 48 additions and 40 deletions

View File

@ -300,17 +300,17 @@ exports.examples = [
title: 'containerBackgroundColor attribute', title: 'containerBackgroundColor attribute',
render: function() { render: function() {
return ( return (
<View> <View style={{backgroundColor: 'yellow'}}>
<View style={{flexDirection: 'row', height: 85}}> <View style={{flexDirection: 'row', position: 'absolute', height: 80}}>
<View style={{backgroundColor: '#ffaaaa', width: 150}} /> <View style={{backgroundColor: '#ffaaaa', width: 140}} />
<View style={{backgroundColor: '#aaaaff', width: 150}} /> <View style={{backgroundColor: '#aaaaff', width: 140}} />
</View> </View>
<Text style={[styles.backgroundColorText, {top: -80}]}> <Text style={styles.backgroundColorText}>
Default containerBackgroundColor (inherited) + backgroundColor wash Default containerBackgroundColor (inherited) + backgroundColor wash
</Text> </Text>
<Text style={[ <Text style={[
styles.backgroundColorText, styles.backgroundColorText,
{top: -70, containerBackgroundColor: 'transparent'}]}> {marginBottom: 5, containerBackgroundColor: 'transparent'}]}>
{"containerBackgroundColor: 'transparent' + backgroundColor wash"} {"containerBackgroundColor: 'transparent' + backgroundColor wash"}
</Text> </Text>
</View> </View>
@ -322,13 +322,13 @@ exports.examples = [
return ( return (
<View> <View>
<Text numberOfLines={1}> <Text numberOfLines={1}>
Maximum of one line no matter now 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>
<Text numberOfLines={2} style={{marginTop: 20}}> <Text numberOfLines={2} style={{marginTop: 20}}>
Maximum of two lines no matter now 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>
<Text style={{marginTop: 20}}> <Text style={{marginTop: 20}}>
No maximum lines specified no matter now 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> </Text>
</View> </View>
); );
@ -337,7 +337,8 @@ exports.examples = [
var styles = StyleSheet.create({ var styles = StyleSheet.create({
backgroundColorText: { backgroundColorText: {
left: 5, margin: 5,
marginBottom: 0,
backgroundColor: 'rgba(100, 100, 100, 0.3)' backgroundColor: 'rgba(100, 100, 100, 0.3)'
}, },
entity: { entity: {

View File

@ -77,13 +77,7 @@ var styles = StyleSheet.create({
paddingHorizontal: 10, paddingHorizontal: 10,
paddingVertical: 5, paddingVertical: 5,
}, },
titleRow: {
flexDirection: 'row',
justifyContent: 'space-between',
backgroundColor: 'transparent',
},
titleText: { titleText: {
backgroundColor: 'transparent',
fontSize: 14, fontSize: 14,
fontWeight: '500', fontWeight: '500',
}, },
@ -101,8 +95,7 @@ var styles = StyleSheet.create({
height: 8, height: 8,
}, },
children: { children: {
backgroundColor: 'transparent', margin: 10,
padding: 10,
} }
}); });

View File

@ -125,13 +125,13 @@ static css_dim_t RCTMeasure(void *context, float width)
} }
if (_color) { if (_color) {
[self _addAttribute:NSForegroundColorAttributeName withValue:self.color toAttributedString:attributedString]; [self _addAttribute:NSForegroundColorAttributeName withValue:_color toAttributedString:attributedString];
} }
if (_isHighlighted) { if (_isHighlighted) {
[self _addAttribute:RCTIsHighlightedAttributeName withValue:@YES toAttributedString:attributedString]; [self _addAttribute:RCTIsHighlightedAttributeName withValue:@YES toAttributedString:attributedString];
} }
if (_textBackgroundColor) { if (_textBackgroundColor) {
[self _addAttribute:NSBackgroundColorAttributeName withValue:self.textBackgroundColor toAttributedString:attributedString]; [self _addAttribute:NSBackgroundColorAttributeName withValue:_textBackgroundColor toAttributedString:attributedString];
} }
UIFont *font = [RCTConvert UIFont:nil withFamily:fontFamily size:fontSize weight:fontWeight style:fontStyle]; UIFont *font = [RCTConvert UIFont:nil withFamily:fontFamily size:fontSize weight:fontWeight style:fontStyle];

View File

@ -32,6 +32,15 @@
return self; return self;
} }
- (void)reactSetFrame:(CGRect)frame
{
// Text looks super weird if its frame is animated.
// This disables the frame animation, without affecting opacity, etc.
[UIView performWithoutAnimation:^{
[super reactSetFrame:frame];
}];
}
- (void)setTextStorage:(NSTextStorage *)textStorage - (void)setTextStorage:(NSTextStorage *)textStorage
{ {
_textStorage = textStorage; _textStorage = textStorage;

View File

@ -34,6 +34,7 @@ RCT_EXPORT_MODULE()
#pragma mark - View properties #pragma mark - View properties
RCT_IGNORE_VIEW_PROPERTY(backgroundColor);
RCT_REMAP_VIEW_PROPERTY(containerBackgroundColor, backgroundColor, UIColor) RCT_REMAP_VIEW_PROPERTY(containerBackgroundColor, backgroundColor, UIColor)
#pragma mark - Shadow properties #pragma mark - Shadow properties

View File

@ -109,8 +109,8 @@ typedef NSArray CGColorArray;
typedef id NSPropertyList; typedef id NSPropertyList;
+ (NSPropertyList)NSPropertyList:(id)json; + (NSPropertyList)NSPropertyList:(id)json;
typedef BOOL css_overflow; typedef BOOL css_clip_t;
+ (css_overflow)css_overflow:(id)json; + (css_clip_t)css_clip_t:(id)json;
+ (css_flex_direction_t)css_flex_direction_t:(id)json; + (css_flex_direction_t)css_flex_direction_t:(id)json;
+ (css_justify_t)css_justify_t:(id)json; + (css_justify_t)css_justify_t:(id)json;
+ (css_align_t)css_align_t:(id)json; + (css_align_t)css_align_t:(id)json;

View File

@ -916,10 +916,10 @@ static id RCTConvertPropertyListValue(id json)
return RCTConvertPropertyListValue(json); return RCTConvertPropertyListValue(json);
} }
RCT_ENUM_CONVERTER(css_overflow, (@{ RCT_ENUM_CONVERTER(css_clip_t, (@{
@"hidden": @NO, @"hidden": @YES,
@"visible": @YES @"visible": @NO
}), YES, boolValue) }), NO, boolValue)
RCT_ENUM_CONVERTER(css_flex_direction_t, (@{ RCT_ENUM_CONVERTER(css_flex_direction_t, (@{
@"row": @(CSS_FLEX_DIRECTION_ROW), @"row": @(CSS_FLEX_DIRECTION_ROW),

View File

@ -13,6 +13,7 @@
#import "RCTLog.h" #import "RCTLog.h"
#import "RCTSparseArray.h" #import "RCTSparseArray.h"
#import "RCTUtils.h" #import "RCTUtils.h"
#import "UIView+React.h"
typedef void (^RCTActionBlock)(RCTShadowView *shadowViewSelf, id value); typedef void (^RCTActionBlock)(RCTShadowView *shadowViewSelf, id value);
typedef void (^RCTResetActionBlock)(RCTShadowView *shadowViewSelf); typedef void (^RCTResetActionBlock)(RCTShadowView *shadowViewSelf);
@ -38,7 +39,6 @@ typedef enum {
NSMutableArray *_reactSubviews; NSMutableArray *_reactSubviews;
BOOL _recomputePadding; BOOL _recomputePadding;
BOOL _recomputeMargin; BOOL _recomputeMargin;
BOOL _isBGColorExplicitlySet;
float _paddingMetaProps[META_PROP_COUNT]; float _paddingMetaProps[META_PROP_COUNT];
float _marginMetaProps[META_PROP_COUNT]; float _marginMetaProps[META_PROP_COUNT];
} }
@ -167,22 +167,20 @@ static void RCTProcessMetaProps(const float metaProps[META_PROP_COUNT], float st
- (NSDictionary *)processBackgroundColor:(NSMutableSet *)applierBlocks parentProperties:(NSDictionary *)parentProperties - (NSDictionary *)processBackgroundColor:(NSMutableSet *)applierBlocks parentProperties:(NSDictionary *)parentProperties
{ {
if (!_isBGColorExplicitlySet) { if (!_backgroundColor) {
UIColor *parentBackgroundColor = parentProperties[RCTBackgroundColorProp]; UIColor *parentBackgroundColor = parentProperties[RCTBackgroundColorProp];
if (parentBackgroundColor && ![_backgroundColor isEqual:parentBackgroundColor]) { if (parentBackgroundColor) {
_backgroundColor = parentBackgroundColor;
[applierBlocks addObject:^(RCTSparseArray *viewRegistry) { [applierBlocks addObject:^(RCTSparseArray *viewRegistry) {
UIView *view = viewRegistry[_reactTag]; UIView *view = viewRegistry[_reactTag];
view.backgroundColor = parentBackgroundColor; [view reactSetInheritedBackgroundColor:parentBackgroundColor];
}]; }];
} }
} } else {
if (_isBGColorExplicitlySet) {
// Update parent properties for children // Update parent properties for children
NSMutableDictionary *properties = [NSMutableDictionary dictionaryWithDictionary:parentProperties]; NSMutableDictionary *properties = [NSMutableDictionary dictionaryWithDictionary:parentProperties];
CGFloat alpha = CGColorGetAlpha(_backgroundColor.CGColor); CGFloat alpha = CGColorGetAlpha(_backgroundColor.CGColor);
if (alpha < 1.0) { if (alpha < 1.0) {
// If we see partial transparency, start propagating full transparency // If bg is non-opaque, don't propagate further
properties[RCTBackgroundColorProp] = [UIColor clearColor]; properties[RCTBackgroundColorProp] = [UIColor clearColor];
} else { } else {
properties[RCTBackgroundColorProp] = _backgroundColor; properties[RCTBackgroundColorProp] = _backgroundColor;
@ -516,7 +514,6 @@ RCT_STYLE_PROPERTY(FlexWrap, flexWrap, flex_wrap, css_wrap_type_t)
- (void)setBackgroundColor:(UIColor *)color - (void)setBackgroundColor:(UIColor *)color
{ {
_backgroundColor = color; _backgroundColor = color;
_isBGColorExplicitlySet = YES;
[self dirtyPropagation]; [self dirtyPropagation];
} }

View File

@ -102,10 +102,7 @@ RCT_REMAP_VIEW_PROPERTY(shadowOffset, layer.shadowOffset, CGSize);
RCT_REMAP_VIEW_PROPERTY(shadowOpacity, layer.shadowOpacity, float) RCT_REMAP_VIEW_PROPERTY(shadowOpacity, layer.shadowOpacity, float)
RCT_REMAP_VIEW_PROPERTY(shadowRadius, layer.shadowRadius, CGFloat) RCT_REMAP_VIEW_PROPERTY(shadowRadius, layer.shadowRadius, CGFloat)
RCT_REMAP_VIEW_PROPERTY(transformMatrix, layer.transform, CATransform3D) RCT_REMAP_VIEW_PROPERTY(transformMatrix, layer.transform, CATransform3D)
RCT_CUSTOM_VIEW_PROPERTY(overflow, css_overflow, RCTView) RCT_REMAP_VIEW_PROPERTY(overflow, clipsToBounds, css_clip_t)
{
view.clipsToBounds = json ? ![RCTConvert css_overflow:json] : defaultView.clipsToBounds;
}
RCT_CUSTOM_VIEW_PROPERTY(pointerEvents, RCTPointerEvents, RCTView) RCT_CUSTOM_VIEW_PROPERTY(pointerEvents, RCTPointerEvents, RCTView)
{ {
if ([view respondsToSelector:@selector(setPointerEvents:)]) { if ([view respondsToSelector:@selector(setPointerEvents:)]) {
@ -260,7 +257,7 @@ RCT_EXPORT_SHADOW_PROPERTY(paddingBottom, CGFloat)
RCT_EXPORT_SHADOW_PROPERTY(paddingLeft, CGFloat) RCT_EXPORT_SHADOW_PROPERTY(paddingLeft, CGFloat)
RCT_EXPORT_SHADOW_PROPERTY(paddingVertical, CGFloat) RCT_EXPORT_SHADOW_PROPERTY(paddingVertical, CGFloat)
RCT_EXPORT_SHADOW_PROPERTY(paddingHorizontal, CGFloat) RCT_EXPORT_SHADOW_PROPERTY(paddingHorizontal, CGFloat)
RCT_EXPORT_SHADOW_PROPERTY(padding, CGFloat); RCT_EXPORT_SHADOW_PROPERTY(padding, CGFloat)
RCT_EXPORT_SHADOW_PROPERTY(flex, CGFloat) RCT_EXPORT_SHADOW_PROPERTY(flex, CGFloat)
RCT_EXPORT_SHADOW_PROPERTY(flexDirection, css_flex_direction_t) RCT_EXPORT_SHADOW_PROPERTY(flexDirection, css_flex_direction_t)

View File

@ -21,6 +21,11 @@
*/ */
- (void)reactSetFrame:(CGRect)frame; - (void)reactSetFrame:(CGRect)frame;
/**
* Used to improve performance when compositing views with translucent content.
*/
- (void)reactSetInheritedBackgroundColor:(UIColor *)inheritedBackgroundColor;
/** /**
* This method finds and returns the containing view controller for the view. * This method finds and returns the containing view controller for the view.
*/ */

View File

@ -83,6 +83,11 @@
self.layer.bounds = bounds; self.layer.bounds = bounds;
} }
- (void)reactSetInheritedBackgroundColor:(UIColor *)inheritedBackgroundColor
{
self.backgroundColor = inheritedBackgroundColor;
}
- (UIViewController *)backingViewController - (UIViewController *)backingViewController
{ {
id responder = [self nextResponder]; id responder = [self nextResponder];