From fb67612e0b0dd8e845567e1fa21e9d368acc4698 Mon Sep 17 00:00:00 2001 From: Omar Manjarrez Osornio Date: Tue, 6 Aug 2024 15:36:52 -0700 Subject: [PATCH] Revert D60453404: feat(iOS): implement automicallyAdjustsKeyboardInsets for new arch Differential Revision: D60453404 Original commit changeset: bd7ce5bac8fa Original Phabricator Diff: D60453404 fbshipit-source-id: cda549be11288fa6cda03a4e6798125bac3c95e2 --- .../ScrollView/RCTScrollViewComponentView.h | 9 -- .../ScrollView/RCTScrollViewComponentView.mm | 110 ------------------ .../TextInput/RCTTextInputComponentView.mm | 28 ----- .../components/scrollview/ScrollViewProps.cpp | 9 -- .../components/scrollview/ScrollViewProps.h | 1 - 5 files changed, 157 deletions(-) diff --git a/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.h b/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.h index 12f4209f63a..8edb46868b1 100644 --- a/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.h +++ b/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.h @@ -35,9 +35,6 @@ NS_ASSUME_NONNULL_BEGIN */ @property (nonatomic, strong, readonly) UIScrollView *scrollView; -/** Focus area of newly-activated text input relative to the window to compare against UIKeyboardFrameBegin/End */ -@property (nonatomic, assign) CGRect firstResponderFocus; - /* * Returns the subview of the scroll view that the component uses to mount all subcomponents into. That's useful to * separate component views from auxiliary views to be able to reliably implement pull-to-refresh- and RTL-related @@ -62,10 +59,4 @@ NS_ASSUME_NONNULL_BEGIN @end -@interface UIView (RCTScrollViewComponentView) - -- (void)reactUpdateResponderOffsetForScrollView:(RCTScrollViewComponentView *)scrollView; - -@end - NS_ASSUME_NONNULL_END diff --git a/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm b/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm index ba0709a65ef..899d38bc249 100644 --- a/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm +++ b/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm @@ -98,8 +98,6 @@ RCTSendScrollEventForNativeAnimations_DEPRECATED(UIScrollView *scrollView, NSInt // some other part of the system scrolls scroll view. BOOL _isUserTriggeredScrolling; BOOL _shouldUpdateContentInsetAdjustmentBehavior; - BOOL _automaticallyAdjustKeyboardInsets; - BOOL _inverted; CGPoint _contentOffsetWhenClipped; @@ -122,7 +120,6 @@ RCTSendScrollEventForNativeAnimations_DEPRECATED(UIScrollView *scrollView, NSInt - (instancetype)initWithFrame:(CGRect)frame { if (self = [super initWithFrame:frame]) { - [self _registerKeyboardListener]; _props = ScrollViewShadowNode::defaultSharedProps(); _scrollView = [[RCTEnhancedScrollView alloc] initWithFrame:self.bounds]; _scrollView.clipsToBounds = _props->getClipsContentToBounds(); @@ -131,8 +128,6 @@ RCTSendScrollEventForNativeAnimations_DEPRECATED(UIScrollView *scrollView, NSInt ((RCTEnhancedScrollView *)_scrollView).overridingDelegate = self; _isUserTriggeredScrolling = NO; _shouldUpdateContentInsetAdjustmentBehavior = YES; - _automaticallyAdjustKeyboardInsets = YES; - _inverted = NO; [self addSubview:_scrollView]; _containerView = [[UIView alloc] initWithFrame:CGRectZero]; @@ -154,103 +149,6 @@ RCTSendScrollEventForNativeAnimations_DEPRECATED(UIScrollView *scrollView, NSInt [self.scrollViewDelegateSplitter removeAllDelegates]; } -- (void)_registerKeyboardListener -{ - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(_keyboardWillChangeFrame:) - name:UIKeyboardWillChangeFrameNotification - object:nil]; -} - -- (void)_unregisterKeyboardListener -{ - [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillChangeFrameNotification object:nil]; -} - -- (void)_keyboardWillChangeFrame:(NSNotification *)notification -{ - if (!_automaticallyAdjustKeyboardInsets) { - return; - } - BOOL isHorizontal = _scrollView.contentSize.width > self.frame.size.width; - if (isHorizontal) { - return; - } - - double duration = [notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue]; - - UIViewAnimationCurve curve = - (UIViewAnimationCurve)[notification.userInfo[UIKeyboardAnimationCurveUserInfoKey] unsignedIntegerValue]; - CGRect beginFrame = [notification.userInfo[UIKeyboardFrameBeginUserInfoKey] CGRectValue]; - CGRect endFrame = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue]; - - CGPoint absoluteViewOrigin = [self convertPoint:self.bounds.origin toView:nil]; - CGFloat scrollViewLowerY = _inverted ? absoluteViewOrigin.y : absoluteViewOrigin.y + self.bounds.size.height; - - UIEdgeInsets newEdgeInsets = _scrollView.contentInset; - CGFloat inset = MAX(scrollViewLowerY - endFrame.origin.y, 0); - if (_inverted) { - newEdgeInsets.top = MAX(inset, _scrollView.contentInset.top); - } else { - newEdgeInsets.bottom = MAX(inset, _scrollView.contentInset.bottom); - } - - CGPoint newContentOffset = _scrollView.contentOffset; - self.firstResponderFocus = CGRectNull; - - CGFloat contentDiff = 0; - if ([[UIApplication sharedApplication] sendAction:@selector(reactUpdateResponderOffsetForScrollView:) - to:nil - from:self - forEvent:nil]) { - // Inner text field focusedS - CGFloat focusEnd = CGRectGetMaxY(self.firstResponderFocus); - BOOL didFocusExternalTextField = focusEnd == INFINITY; - if (!didFocusExternalTextField && focusEnd > endFrame.origin.y) { - // Text field active region is below visible area with keyboard - update diff to bring into view - contentDiff = endFrame.origin.y - focusEnd; - } - } else if (endFrame.origin.y <= beginFrame.origin.y) { - // Keyboard opened for other reason - contentDiff = endFrame.origin.y - beginFrame.origin.y; - } - if (_inverted) { - newContentOffset.y += contentDiff; - } else { - newContentOffset.y -= contentDiff; - } - - if (@available(iOS 14.0, *)) { - // On iOS when Prefer Cross-Fade Transitions is enabled, the keyboard position - // & height is reported differently (0 instead of Y position value matching height of frame) - // Fixes similar issue we saw with https://github.com/facebook/react-native/pull/34503 - if (UIAccessibilityPrefersCrossFadeTransitions() && endFrame.size.height == 0) { - newContentOffset.y = 0; - newEdgeInsets.bottom = 0; - } - } - - [UIView animateWithDuration:duration - delay:0.0 - options:animationOptionsWithCurve(curve) - animations:^{ - self->_scrollView.contentInset = newEdgeInsets; - self->_scrollView.verticalScrollIndicatorInsets = newEdgeInsets; - [self scrollToOffset:newContentOffset animated:NO]; - } - completion:nil]; -} - -static inline UIViewAnimationOptions animationOptionsWithCurve(UIViewAnimationCurve curve) -{ - // UIViewAnimationCurve #7 is used for keyboard and therefore private - so we can't use switch/case here. - // source: https://stackoverflow.com/a/7327374/5281431 - RCTAssert( - UIViewAnimationCurveLinear << 16 == UIViewAnimationOptionCurveLinear, - @"Unexpected implementation of UIViewAnimationCurve"); - return curve << 16; -} - - (RCTGenericDelegateSplitter> *)scrollViewDelegateSplitter { return ((RCTEnhancedScrollView *)_scrollView).delegateSplitter; @@ -327,14 +225,6 @@ static inline UIViewAnimationOptions animationOptionsWithCurve(UIViewAnimationCu MAP_SCROLL_VIEW_PROP(showsHorizontalScrollIndicator); MAP_SCROLL_VIEW_PROP(showsVerticalScrollIndicator); - if (oldScrollViewProps.isInvertedVirtualizedList != newScrollViewProps.isInvertedVirtualizedList) { - _inverted = newScrollViewProps.isInvertedVirtualizedList; - } - - if (oldScrollViewProps.automaticallyAdjustKeyboardInsets != newScrollViewProps.automaticallyAdjustKeyboardInsets) { - _automaticallyAdjustKeyboardInsets = newScrollViewProps.automaticallyAdjustKeyboardInsets; - } - if (oldScrollViewProps.scrollIndicatorInsets != newScrollViewProps.scrollIndicatorInsets) { _scrollView.scrollIndicatorInsets = RCTUIEdgeInsetsFromEdgeInsets(newScrollViewProps.scrollIndicatorInsets); } diff --git a/packages/react-native/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm b/packages/react-native/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm index a44f30828fc..8e7cc58c43a 100644 --- a/packages/react-native/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm +++ b/packages/react-native/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm @@ -12,7 +12,6 @@ #import #import -#import #import #import #import @@ -23,9 +22,6 @@ #import "RCTFabricComponentsPlugins.h" -/** Native iOS text field bottom keyboard offset amount */ -static const CGFloat kSingleLineKeyboardBottomOffset = 15.0; - using namespace facebook::react; @interface RCTTextInputComponentView () @@ -100,30 +96,6 @@ static NSSet *returnKeyTypesSet; [self _restoreTextSelection]; } -- (void)reactUpdateResponderOffsetForScrollView:(RCTScrollViewComponentView *)scrollView -{ - if (![self isDescendantOfView:scrollView.scrollView]) { - // View is outside scroll view - return; - } - - UITextRange *selectedTextRange = _backedTextInputView.selectedTextRange; - UITextSelectionRect *selection = [_backedTextInputView selectionRectsForRange:selectedTextRange].firstObject; - CGRect focusRect; - if (selection == nil) { - // No active selection or caret - fallback to entire input frame - focusRect = self.bounds; - } else { - // Focus on text selection frame - focusRect = selection.rect; - BOOL isMultiline = [_backedTextInputView isKindOfClass:[UITextView class]]; - if (!isMultiline) { - focusRect.size.height += kSingleLineKeyboardBottomOffset; - } - } - scrollView.firstResponderFocus = [self convertRect:focusRect toView:nil]; -} - #pragma mark - RCTViewComponentView overrides - (NSObject *)accessibilityElement diff --git a/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewProps.cpp b/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewProps.cpp index 133d3ff226e..54a72d28088 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewProps.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewProps.cpp @@ -91,15 +91,6 @@ ScrollViewProps::ScrollViewProps( "automaticallyAdjustsScrollIndicatorInsets", sourceProps.automaticallyAdjustsScrollIndicatorInsets, true)), - automaticallyAdjustKeyboardInsets( - CoreFeatures::enablePropIteratorSetter - ? sourceProps.automaticallyAdjustKeyboardInsets - : convertRawProp( - context, - rawProps, - "automaticallyAdjustKeyboardInsets", - sourceProps.automaticallyAdjustKeyboardInsets, - true)), decelerationRate( CoreFeatures::enablePropIteratorSetter ? sourceProps.decelerationRate diff --git a/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewProps.h b/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewProps.h index 0a252109a3d..d93441a08ff 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewProps.h +++ b/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewProps.h @@ -40,7 +40,6 @@ class ScrollViewProps final : public ViewProps { bool centerContent{}; bool automaticallyAdjustContentInsets{}; bool automaticallyAdjustsScrollIndicatorInsets{true}; - bool automaticallyAdjustKeyboardInsets{true}; Float decelerationRate{0.998f}; Float endDraggingSensitivityMultiplier{1}; bool enableSyncOnScroll{false};