From 65c014d19f933771a69c7cbccdbb744330cf13a3 Mon Sep 17 00:00:00 2001 From: zhongwuzw Date: Sun, 3 Mar 2019 19:55:51 -0800 Subject: [PATCH] Keep placeholder attributes sync with text input text's attributes (#23738) Summary: We need to keep placeholder attributes sync with text input's text attributes, like `font`,`kern` ....., to keep style the same. Also fixes #19002 . [iOS] [Fixed] - Keep placeholder attributes sync with text input text's attributes Pull Request resolved: https://github.com/facebook/react-native/pull/23738 Differential Revision: D14298482 Pulled By: cpojer fbshipit-source-id: 3555091bf3bc01e4b026d5a4cdbe93b4122106e8 --- .../Text/TextInput/Multiline/RCTUITextView.m | 16 ++++++++++++++-- .../Text/TextInput/Singleline/RCTUITextField.m | 5 +++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/Libraries/Text/TextInput/Multiline/RCTUITextView.m b/Libraries/Text/TextInput/Multiline/RCTUITextView.m index 5734672d13..0ac217c101 100644 --- a/Libraries/Text/TextInput/Multiline/RCTUITextView.m +++ b/Libraries/Text/TextInput/Multiline/RCTUITextView.m @@ -82,7 +82,7 @@ static UIColor *defaultPlaceholderColor() - (void)setPlaceholder:(NSString *)placeholder { _placeholder = placeholder; - _placeholderView.text = _placeholder; + _placeholderView.attributedText = [[NSAttributedString alloc] initWithString:_placeholder ?: @"" attributes:[self placeholderEffectiveTextAttributes]]; } - (void)setPlaceholderColor:(UIColor *)placeholderColor @@ -98,7 +98,8 @@ static UIColor *defaultPlaceholderColor() } self.typingAttributes = reactTextAttributes.effectiveTextAttributes; _reactTextAttributes = reactTextAttributes; - _placeholderView.font = self.font ?: defaultPlaceholderFont(); + // Update placeholder text attributes + [self setPlaceholder:_placeholder]; } - (RCTTextAttributes *)reactTextAttributes @@ -249,6 +250,17 @@ static UIColor *defaultPlaceholderColor() _placeholderView.hidden = !isVisible; } +- (NSDictionary *)placeholderEffectiveTextAttributes +{ + NSDictionary *effectiveTextAttributes = @{ + NSFontAttributeName: _reactTextAttributes.effectiveFont ?: defaultPlaceholderFont(), + NSForegroundColorAttributeName: self.placeholderColor ?: defaultPlaceholderColor(), + NSKernAttributeName:isnan(_reactTextAttributes.letterSpacing) ? @0 : @(_reactTextAttributes.letterSpacing) + }; + + return effectiveTextAttributes; +} + #pragma mark - Utility Methods - (void)copyTextAttributesFrom:(NSAttributedString *)sourceString diff --git a/Libraries/Text/TextInput/Singleline/RCTUITextField.m b/Libraries/Text/TextInput/Singleline/RCTUITextField.m index e092caa5d3..b4df1a9d7a 100644 --- a/Libraries/Text/TextInput/Singleline/RCTUITextField.m +++ b/Libraries/Text/TextInput/Singleline/RCTUITextField.m @@ -70,6 +70,7 @@ } self.defaultTextAttributes = reactTextAttributes.effectiveTextAttributes; _reactTextAttributes = reactTextAttributes; + [self _updatePlaceholder]; } - (RCTTextAttributes *)reactTextAttributes @@ -87,6 +88,10 @@ if (_placeholderColor) { [attributes setObject:_placeholderColor forKey:NSForegroundColorAttributeName]; } + // Kerning + if (!isnan(_reactTextAttributes.letterSpacing)) { + attributes[NSKernAttributeName] = @(_reactTextAttributes.letterSpacing); + } self.attributedPlaceholder = [[NSAttributedString alloc] initWithString:self.placeholder attributes:attributes];