From e075a3f424f0a5433357d1c92eb7ab8a869ab612 Mon Sep 17 00:00:00 2001 From: Samuel Susla Date: Fri, 7 Jul 2023 05:44:24 -0700 Subject: [PATCH] Back out "Fix TextInput vertical alignment issue when using lineHeight prop on iOS (Paper - old arch)" (#38235) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/38235 changelog: [internal] Original commit changeset: faece0940b15 Original Phabricator Diff: D46086661 This PR broke 50 diffs. Let's back it out. I will communicate this to the PR owner with an example of what went wrong. This causes a slight difference in text render: {F1043017930} Reviewed By: javache Differential Revision: D47284841 fbshipit-source-id: 29d28f62d3997740b2186bd60b327a0d009c4a6b --- .../Libraries/Text/RCTTextAttributes.m | 14 +++---------- .../Text/TextInput/Multiline/RCTUITextView.h | 3 --- .../Text/TextInput/Multiline/RCTUITextView.m | 8 ------- .../RCTBackedTextInputViewProtocol.h | 3 --- .../TextInput/RCTBaseTextInputShadowView.m | 18 ---------------- .../Text/TextInput/RCTBaseTextInputView.h | 2 -- .../Text/TextInput/RCTBaseTextInputView.m | 21 +++---------------- .../TextInput/Singleline/RCTUITextField.h | 2 -- .../TextInput/Singleline/RCTUITextField.m | 19 +---------------- 9 files changed, 7 insertions(+), 83 deletions(-) diff --git a/packages/react-native/Libraries/Text/RCTTextAttributes.m b/packages/react-native/Libraries/Text/RCTTextAttributes.m index c2ca6407a9778f..c8323388ce684b 100644 --- a/packages/react-native/Libraries/Text/RCTTextAttributes.m +++ b/packages/react-native/Libraries/Text/RCTTextAttributes.m @@ -130,12 +130,9 @@ - (NSParagraphStyle *)effectiveParagraphStyle if (!isnan(_lineHeight)) { CGFloat lineHeight = _lineHeight * self.effectiveFontSizeMultiplier; - // text with lineHeight lower then font.lineHeight does not correctly vertically align - if (lineHeight > self.effectiveFont.lineHeight) { - paragraphStyle.minimumLineHeight = lineHeight; - paragraphStyle.maximumLineHeight = lineHeight; - isParagraphStyleUsed = YES; - } + paragraphStyle.minimumLineHeight = lineHeight; + paragraphStyle.maximumLineHeight = lineHeight; + isParagraphStyleUsed = YES; } if (isParagraphStyleUsed) { @@ -175,11 +172,6 @@ - (NSParagraphStyle *)effectiveParagraphStyle NSParagraphStyle *paragraphStyle = [self effectiveParagraphStyle]; if (paragraphStyle) { attributes[NSParagraphStyleAttributeName] = paragraphStyle; - // The baseline aligns the text vertically in the line height - if (!isnan(paragraphStyle.maximumLineHeight) && paragraphStyle.maximumLineHeight >= font.lineHeight) { - CGFloat baseLineOffset = (paragraphStyle.maximumLineHeight - font.lineHeight) / 2.0; - attributes[NSBaselineOffsetAttributeName] = @(baseLineOffset); - } } // Decoration diff --git a/packages/react-native/Libraries/Text/TextInput/Multiline/RCTUITextView.h b/packages/react-native/Libraries/Text/TextInput/Multiline/RCTUITextView.h index b02d7964f76a5d..205f9943262add 100644 --- a/packages/react-native/Libraries/Text/TextInput/Multiline/RCTUITextView.h +++ b/packages/react-native/Libraries/Text/TextInput/Multiline/RCTUITextView.h @@ -27,9 +27,6 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, assign, readonly) BOOL dictationRecognizing; @property (nonatomic, copy, nullable) NSString *placeholder; @property (nonatomic, strong, nullable) UIColor *placeholderColor; -@property (nonatomic, assign) CGRect fragmentViewContainerBounds; -@property (nonatomic, assign) UIEdgeInsets textBorderInsets; -@property (nonatomic, assign) UIControlContentVerticalAlignment contentVerticalAlignment; @property (nonatomic, assign) CGFloat preferredMaxLayoutWidth; diff --git a/packages/react-native/Libraries/Text/TextInput/Multiline/RCTUITextView.m b/packages/react-native/Libraries/Text/TextInput/Multiline/RCTUITextView.m index 27565331b98ad3..ce8a77ec6c1275 100644 --- a/packages/react-native/Libraries/Text/TextInput/Multiline/RCTUITextView.m +++ b/packages/react-native/Libraries/Text/TextInput/Multiline/RCTUITextView.m @@ -169,14 +169,6 @@ - (void)paste:(id)sender [super paste:sender]; } -- (void)setTextBorderInsetsAndFrame:(CGRect)bounds textBorderInsets:(UIEdgeInsets)textBorderInsets -{ - _textBorderInsets = textBorderInsets; - // We apply `borderInsets` as `RCTUITextView` layout offset. - self.frame = UIEdgeInsetsInsetRect(bounds, textBorderInsets); - [self setNeedsLayout]; -} - // Turn off scroll animation to fix flaky scrolling. // This is only necessary for iOS <= 14. #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED < 140000 diff --git a/packages/react-native/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h b/packages/react-native/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h index 55b8946c0f664b..a8719ecd4d0165 100644 --- a/packages/react-native/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h +++ b/packages/react-native/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h @@ -35,8 +35,6 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, assign, readonly) CGFloat zoomScale; @property (nonatomic, assign, readonly) CGPoint contentOffset; @property (nonatomic, assign, readonly) UIEdgeInsets contentInset; -@property (nonatomic, assign) CGRect fragmentViewContainerBounds; -@property (nonatomic, assign) UIControlContentVerticalAlignment contentVerticalAlignment; // This protocol disallows direct access to `selectedTextRange` property because // unwise usage of it can break the `delegate` behavior. So, we always have to @@ -45,7 +43,6 @@ NS_ASSUME_NONNULL_BEGIN // If the change was a result of user actions (like typing or touches), we MUST notify the delegate. - (void)setSelectedTextRange:(nullable UITextRange *)selectedTextRange NS_UNAVAILABLE; - (void)setSelectedTextRange:(nullable UITextRange *)selectedTextRange notifyDelegate:(BOOL)notifyDelegate; -- (void)setTextBorderInsetsAndFrame:(CGRect)bounds textBorderInsets:(UIEdgeInsets)textBorderInsets; // This protocol disallows direct access to `text` property because // unwise usage of it can break the `attributeText` behavior. diff --git a/packages/react-native/Libraries/Text/TextInput/RCTBaseTextInputShadowView.m b/packages/react-native/Libraries/Text/TextInput/RCTBaseTextInputShadowView.m index 396e41e44a64bf..04d2446f86d9b3 100644 --- a/packages/react-native/Libraries/Text/TextInput/RCTBaseTextInputShadowView.m +++ b/packages/react-native/Libraries/Text/TextInput/RCTBaseTextInputShadowView.m @@ -177,24 +177,6 @@ - (void)uiManagerWillPerformMounting baseTextInputView.textAttributes = textAttributes; baseTextInputView.reactBorderInsets = borderInsets; - - // Fixes iOS issue caused by adding paragraphStyle.maximumLineHeight to an iOS UITextField. - // The CALayer _UITextLayoutFragmentView does not align correctly (see issue #28012). - if (!isnan(textAttributes.lineHeight) && !isnan(textAttributes.effectiveFont.lineHeight)) { - CGFloat effectiveLineHeight = textAttributes.lineHeight * textAttributes.effectiveFontSizeMultiplier; - CGFloat fontLineHeight = textAttributes.effectiveFont.lineHeight; - if (effectiveLineHeight >= fontLineHeight * 2.0) { - CGFloat height = self.layoutMetrics.frame.size.height; - CGFloat width = self.layoutMetrics.frame.size.width; - // sets the same origin.y coordinates for _UITextLayoutFragmentView and UITextField frame - baseTextInputView.contentVerticalAlignment = UIControlContentVerticalAlignmentTop; - // vertically center aligns the _UITextLayoutFragmentView in the parent UITextField - CGFloat padding = (height - effectiveLineHeight) / 2.0; - baseTextInputView.fragmentViewContainerBounds = CGRectMake(0, padding, width, effectiveLineHeight); - } - } else { - baseTextInputView.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter; - } baseTextInputView.reactPaddingInsets = paddingInsets; if (newAttributedText) { diff --git a/packages/react-native/Libraries/Text/TextInput/RCTBaseTextInputView.h b/packages/react-native/Libraries/Text/TextInput/RCTBaseTextInputView.h index 7258c36e1d8b8f..209947de9b4aaa 100644 --- a/packages/react-native/Libraries/Text/TextInput/RCTBaseTextInputView.h +++ b/packages/react-native/Libraries/Text/TextInput/RCTBaseTextInputView.h @@ -31,8 +31,6 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, strong, nullable) RCTTextAttributes *textAttributes; @property (nonatomic, assign) UIEdgeInsets reactPaddingInsets; @property (nonatomic, assign) UIEdgeInsets reactBorderInsets; -@property (nonatomic, assign) CGRect fragmentViewContainerBounds; -@property (nonatomic, assign) UIControlContentVerticalAlignment contentVerticalAlignment; @property (nonatomic, copy, nullable) RCTDirectEventBlock onContentSizeChange; @property (nonatomic, copy, nullable) RCTDirectEventBlock onSelectionChange; diff --git a/packages/react-native/Libraries/Text/TextInput/RCTBaseTextInputView.m b/packages/react-native/Libraries/Text/TextInput/RCTBaseTextInputView.m index ca672bea307265..cb293db64411b4 100644 --- a/packages/react-native/Libraries/Text/TextInput/RCTBaseTextInputView.m +++ b/packages/react-native/Libraries/Text/TextInput/RCTBaseTextInputView.m @@ -76,22 +76,6 @@ - (void)enforceTextAttributesIfNeeded backedTextInputView.defaultTextAttributes = textAttributes; } -// Fixes iOS alignment issue caused by adding paragraphStyle.maximumLineHeight to an iOS UITextField -// vertically aligns _UITextLayoutFragmentView with the parent view UITextField -- (void)setContentVerticalAlignment:(UIControlContentVerticalAlignment)contentVerticalAlignment -{ - _contentVerticalAlignment = contentVerticalAlignment; - self.backedTextInputView.contentVerticalAlignment = contentVerticalAlignment; -} - -// Custom bounds used to control vertical position of CALayer _UITextLayoutFragmentView -// _UITextLayoutFragmentView is the CALayer of UITextField -- (void)setFragmentViewContainerBounds:(CGRect)fragmentViewContainerBounds -{ - _fragmentViewContainerBounds = fragmentViewContainerBounds; - self.backedTextInputView.fragmentViewContainerBounds = fragmentViewContainerBounds; -} - - (void)setReactPaddingInsets:(UIEdgeInsets)reactPaddingInsets { _reactPaddingInsets = reactPaddingInsets; @@ -103,8 +87,9 @@ - (void)setReactPaddingInsets:(UIEdgeInsets)reactPaddingInsets - (void)setReactBorderInsets:(UIEdgeInsets)reactBorderInsets { _reactBorderInsets = reactBorderInsets; - // Borders are added using insets (UITextField textRectForBound, UITextView setFrame) - [self.backedTextInputView setTextBorderInsetsAndFrame:self.bounds textBorderInsets:reactBorderInsets]; + // We apply `borderInsets` as `backedTextInputView` layout offset. + self.backedTextInputView.frame = UIEdgeInsetsInsetRect(self.bounds, reactBorderInsets); + [self setNeedsLayout]; } - (NSAttributedString *)attributedText diff --git a/packages/react-native/Libraries/Text/TextInput/Singleline/RCTUITextField.h b/packages/react-native/Libraries/Text/TextInput/Singleline/RCTUITextField.h index b581589f1dfcb1..91f8eb087acf87 100644 --- a/packages/react-native/Libraries/Text/TextInput/Singleline/RCTUITextField.h +++ b/packages/react-native/Libraries/Text/TextInput/Singleline/RCTUITextField.h @@ -27,8 +27,6 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, assign, readonly) BOOL dictationRecognizing; @property (nonatomic, strong, nullable) UIColor *placeholderColor; @property (nonatomic, assign) UIEdgeInsets textContainerInset; -@property (nonatomic, assign) CGRect fragmentViewContainerBounds; -@property (nonatomic, assign) UIEdgeInsets textBorderInsets; @property (nonatomic, assign, getter=isEditable) BOOL editable; @property (nonatomic, getter=isScrollEnabled) BOOL scrollEnabled; @property (nonatomic, strong, nullable) NSString *inputAccessoryViewID; diff --git a/packages/react-native/Libraries/Text/TextInput/Singleline/RCTUITextField.m b/packages/react-native/Libraries/Text/TextInput/Singleline/RCTUITextField.m index 1d46459e0b8400..4d0afd97ae682a 100644 --- a/packages/react-native/Libraries/Text/TextInput/Singleline/RCTUITextField.m +++ b/packages/react-native/Libraries/Text/TextInput/Singleline/RCTUITextField.m @@ -55,12 +55,6 @@ - (void)setTextContainerInset:(UIEdgeInsets)textContainerInset [self setNeedsLayout]; } -- (void)setTextBorderInsetsAndFrame:(CGRect)bounds textBorderInsets:(UIEdgeInsets)textBorderInsets -{ - _textBorderInsets = textBorderInsets; - [self setNeedsLayout]; -} - - (void)setPlaceholder:(NSString *)placeholder { [super setPlaceholder:placeholder]; @@ -176,18 +170,7 @@ - (CGRect)caretRectForPosition:(UITextPosition *)position - (CGRect)textRectForBounds:(CGRect)bounds { - // Text is vertically aligned to the center - CGFloat leftPadding = _textContainerInset.left + _textBorderInsets.left; - CGFloat rightPadding = _textContainerInset.right + _textBorderInsets.right; - UIEdgeInsets borderAndPaddingInsets = - UIEdgeInsetsMake(_textContainerInset.top, leftPadding, _textContainerInset.bottom, rightPadding); - if (self.fragmentViewContainerBounds.size.height > 0) { - // apply custom bounds to fix iOS UITextField issue with lineHeight - // sets the correct y coordinates for _UITextLayoutFragmentView - return UIEdgeInsetsInsetRect([super textRectForBounds:self.fragmentViewContainerBounds], borderAndPaddingInsets); - } else { - return UIEdgeInsetsInsetRect([super textRectForBounds:bounds], borderAndPaddingInsets); - } + return UIEdgeInsetsInsetRect([super textRectForBounds:bounds], _textContainerInset); } - (CGRect)editingRectForBounds:(CGRect)bounds