From 45c1dc1c65892baa619ec1d5cf08a46e24b67ce5 Mon Sep 17 00:00:00 2001 From: Nick Lockwood Date: Thu, 28 May 2015 09:29:27 -0700 Subject: [PATCH] Fixed text background color Summary: @public This fixes an issue with the containerBackgroundColor property of `` 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 --- Examples/UIExplorer/TextExample.ios.js | 21 +++++++++++---------- Examples/UIExplorer/UIExplorerBlock.js | 9 +-------- Libraries/Text/RCTShadowText.m | 4 ++-- Libraries/Text/RCTText.m | 9 +++++++++ Libraries/Text/RCTTextManager.m | 1 + React/Base/RCTConvert.h | 4 ++-- React/Base/RCTConvert.m | 8 ++++---- React/Views/RCTShadowView.m | 15 ++++++--------- React/Views/RCTViewManager.m | 7 ++----- React/Views/UIView+React.h | 5 +++++ React/Views/UIView+React.m | 5 +++++ 11 files changed, 48 insertions(+), 40 deletions(-) diff --git a/Examples/UIExplorer/TextExample.ios.js b/Examples/UIExplorer/TextExample.ios.js index 10323c7a5..b2fd717ad 100644 --- a/Examples/UIExplorer/TextExample.ios.js +++ b/Examples/UIExplorer/TextExample.ios.js @@ -300,17 +300,17 @@ exports.examples = [ title: 'containerBackgroundColor attribute', render: function() { return ( - - - - + + + + - + Default containerBackgroundColor (inherited) + backgroundColor wash + {marginBottom: 5, containerBackgroundColor: 'transparent'}]}> {"containerBackgroundColor: 'transparent' + backgroundColor wash"} @@ -322,13 +322,13 @@ exports.examples = [ return ( - 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. - 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. - 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. ); @@ -337,7 +337,8 @@ exports.examples = [ var styles = StyleSheet.create({ backgroundColorText: { - left: 5, + margin: 5, + marginBottom: 0, backgroundColor: 'rgba(100, 100, 100, 0.3)' }, entity: { diff --git a/Examples/UIExplorer/UIExplorerBlock.js b/Examples/UIExplorer/UIExplorerBlock.js index 10a2b57cd..649b8994f 100644 --- a/Examples/UIExplorer/UIExplorerBlock.js +++ b/Examples/UIExplorer/UIExplorerBlock.js @@ -77,13 +77,7 @@ var styles = StyleSheet.create({ paddingHorizontal: 10, paddingVertical: 5, }, - titleRow: { - flexDirection: 'row', - justifyContent: 'space-between', - backgroundColor: 'transparent', - }, titleText: { - backgroundColor: 'transparent', fontSize: 14, fontWeight: '500', }, @@ -101,8 +95,7 @@ var styles = StyleSheet.create({ height: 8, }, children: { - backgroundColor: 'transparent', - padding: 10, + margin: 10, } }); diff --git a/Libraries/Text/RCTShadowText.m b/Libraries/Text/RCTShadowText.m index dd880340d..b43cc7f76 100644 --- a/Libraries/Text/RCTShadowText.m +++ b/Libraries/Text/RCTShadowText.m @@ -125,13 +125,13 @@ static css_dim_t RCTMeasure(void *context, float width) } if (_color) { - [self _addAttribute:NSForegroundColorAttributeName withValue:self.color toAttributedString:attributedString]; + [self _addAttribute:NSForegroundColorAttributeName withValue:_color toAttributedString:attributedString]; } if (_isHighlighted) { [self _addAttribute:RCTIsHighlightedAttributeName withValue:@YES toAttributedString:attributedString]; } 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]; diff --git a/Libraries/Text/RCTText.m b/Libraries/Text/RCTText.m index cdb09d4ff..43a926551 100644 --- a/Libraries/Text/RCTText.m +++ b/Libraries/Text/RCTText.m @@ -32,6 +32,15 @@ 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 { _textStorage = textStorage; diff --git a/Libraries/Text/RCTTextManager.m b/Libraries/Text/RCTTextManager.m index 3dbb2ed53..1bcfdf7e6 100644 --- a/Libraries/Text/RCTTextManager.m +++ b/Libraries/Text/RCTTextManager.m @@ -34,6 +34,7 @@ RCT_EXPORT_MODULE() #pragma mark - View properties +RCT_IGNORE_VIEW_PROPERTY(backgroundColor); RCT_REMAP_VIEW_PROPERTY(containerBackgroundColor, backgroundColor, UIColor) #pragma mark - Shadow properties diff --git a/React/Base/RCTConvert.h b/React/Base/RCTConvert.h index 0f73c2829..ee43c1159 100644 --- a/React/Base/RCTConvert.h +++ b/React/Base/RCTConvert.h @@ -109,8 +109,8 @@ typedef NSArray CGColorArray; typedef id NSPropertyList; + (NSPropertyList)NSPropertyList:(id)json; -typedef BOOL css_overflow; -+ (css_overflow)css_overflow:(id)json; +typedef BOOL css_clip_t; ++ (css_clip_t)css_clip_t:(id)json; + (css_flex_direction_t)css_flex_direction_t:(id)json; + (css_justify_t)css_justify_t:(id)json; + (css_align_t)css_align_t:(id)json; diff --git a/React/Base/RCTConvert.m b/React/Base/RCTConvert.m index 0047f8461..3c9143c17 100644 --- a/React/Base/RCTConvert.m +++ b/React/Base/RCTConvert.m @@ -916,10 +916,10 @@ static id RCTConvertPropertyListValue(id json) return RCTConvertPropertyListValue(json); } -RCT_ENUM_CONVERTER(css_overflow, (@{ - @"hidden": @NO, - @"visible": @YES -}), YES, boolValue) +RCT_ENUM_CONVERTER(css_clip_t, (@{ + @"hidden": @YES, + @"visible": @NO +}), NO, boolValue) RCT_ENUM_CONVERTER(css_flex_direction_t, (@{ @"row": @(CSS_FLEX_DIRECTION_ROW), diff --git a/React/Views/RCTShadowView.m b/React/Views/RCTShadowView.m index 6fc7f58b1..b26193f24 100644 --- a/React/Views/RCTShadowView.m +++ b/React/Views/RCTShadowView.m @@ -13,6 +13,7 @@ #import "RCTLog.h" #import "RCTSparseArray.h" #import "RCTUtils.h" +#import "UIView+React.h" typedef void (^RCTActionBlock)(RCTShadowView *shadowViewSelf, id value); typedef void (^RCTResetActionBlock)(RCTShadowView *shadowViewSelf); @@ -38,7 +39,6 @@ typedef enum { NSMutableArray *_reactSubviews; BOOL _recomputePadding; BOOL _recomputeMargin; - BOOL _isBGColorExplicitlySet; float _paddingMetaProps[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 { - if (!_isBGColorExplicitlySet) { + if (!_backgroundColor) { UIColor *parentBackgroundColor = parentProperties[RCTBackgroundColorProp]; - if (parentBackgroundColor && ![_backgroundColor isEqual:parentBackgroundColor]) { - _backgroundColor = parentBackgroundColor; + if (parentBackgroundColor) { [applierBlocks addObject:^(RCTSparseArray *viewRegistry) { UIView *view = viewRegistry[_reactTag]; - view.backgroundColor = parentBackgroundColor; + [view reactSetInheritedBackgroundColor:parentBackgroundColor]; }]; } - } - if (_isBGColorExplicitlySet) { + } else { // Update parent properties for children NSMutableDictionary *properties = [NSMutableDictionary dictionaryWithDictionary:parentProperties]; CGFloat alpha = CGColorGetAlpha(_backgroundColor.CGColor); 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]; } else { properties[RCTBackgroundColorProp] = _backgroundColor; @@ -516,7 +514,6 @@ RCT_STYLE_PROPERTY(FlexWrap, flexWrap, flex_wrap, css_wrap_type_t) - (void)setBackgroundColor:(UIColor *)color { _backgroundColor = color; - _isBGColorExplicitlySet = YES; [self dirtyPropagation]; } diff --git a/React/Views/RCTViewManager.m b/React/Views/RCTViewManager.m index 311167761..d7a93b7e3 100644 --- a/React/Views/RCTViewManager.m +++ b/React/Views/RCTViewManager.m @@ -102,10 +102,7 @@ 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(transformMatrix, layer.transform, CATransform3D) -RCT_CUSTOM_VIEW_PROPERTY(overflow, css_overflow, RCTView) -{ - view.clipsToBounds = json ? ![RCTConvert css_overflow:json] : defaultView.clipsToBounds; -} +RCT_REMAP_VIEW_PROPERTY(overflow, clipsToBounds, css_clip_t) RCT_CUSTOM_VIEW_PROPERTY(pointerEvents, RCTPointerEvents, RCTView) { 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(paddingVertical, 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(flexDirection, css_flex_direction_t) diff --git a/React/Views/UIView+React.h b/React/Views/UIView+React.h index 28bca9db9..cdd65ee96 100644 --- a/React/Views/UIView+React.h +++ b/React/Views/UIView+React.h @@ -21,6 +21,11 @@ */ - (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. */ diff --git a/React/Views/UIView+React.m b/React/Views/UIView+React.m index 6e4a8c45c..a448559ca 100644 --- a/React/Views/UIView+React.m +++ b/React/Views/UIView+React.m @@ -83,6 +83,11 @@ self.layer.bounds = bounds; } +- (void)reactSetInheritedBackgroundColor:(UIColor *)inheritedBackgroundColor +{ + self.backgroundColor = inheritedBackgroundColor; +} + - (UIViewController *)backingViewController { id responder = [self nextResponder];