Skip to content

Commit

Permalink
automaticallyAdjustKeyboardInsets not shifting scrollview content (#4…
Browse files Browse the repository at this point in the history
…6732)

Summary:
Fixes #46595 . It seems #37766 broke the `automaticallyAdjustKeyboardInsets` when input accessory view become first responder.

[IOS] [FIXED] - automaticallyAdjustKeyboardInsets not shifting scrollview content

Pull Request resolved: #46732

Test Plan: Repro please see in ##46595 .

Reviewed By: cipolleschi

Differential Revision: D65072478

Pulled By: javache

fbshipit-source-id: 7d5d7566438d4bb0e1d50074a953b18866e324d3
  • Loading branch information
zhongwuzw authored and blakef committed Dec 9, 2024
1 parent 94e2b5b commit 08976e4
Show file tree
Hide file tree
Showing 6 changed files with 14 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ - (void)reactUpdateResponderOffsetForScrollView:(RCTScrollView *)scrollView
{
if (![self isDescendantOfView:scrollView]) {
// View is outside scroll view
scrollView.firstResponderViewOutsideScrollView = self.backedTextInputView;
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ NS_ASSUME_NONNULL_BEGIN
/** Focus area of newly-activated text input relative to the window to compare against UIKeyboardFrameBegin/End */
@property (nonatomic, assign) CGRect firstResponderFocus;

/** newly-activated text input outside of the scroll view */
@property (nonatomic, weak) UIView *firstResponderViewOutsideScrollView;

/*
* 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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ - (void)_keyboardWillChangeFrame:(NSNotification *)notification
UIViewAnimationCurve curve =
(UIViewAnimationCurve)[notification.userInfo[UIKeyboardAnimationCurveUserInfoKey] unsignedIntegerValue];
CGRect keyboardEndFrame = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGRect keyboardBeginFrame = [notification.userInfo[UIKeyboardFrameBeginUserInfoKey] CGRectValue];

CGPoint absoluteViewOrigin = [self convertPoint:self.bounds.origin toView:nil];
CGFloat scrollViewLowerY = isInverted ? absoluteViewOrigin.y : absoluteViewOrigin.y + self.bounds.size.height;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ - (void)reactUpdateResponderOffsetForScrollView:(RCTScrollViewComponentView *)sc
{
if (![self isDescendantOfView:scrollView.scrollView] || !_backedTextInputView.isFirstResponder) {
// View is outside scroll view or it's not a first responder.
scrollView.firstResponderViewOutsideScrollView = _backedTextInputView;
return;
}

Expand Down
2 changes: 2 additions & 0 deletions packages/react-native/React/Views/ScrollView/RCTScrollView.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@
@property (nonatomic, assign) BOOL inverted;
/** Focus area of newly-activated text input relative to the window to compare against UIKeyboardFrameBegin/End */
@property (nonatomic, assign) CGRect firstResponderFocus;
/** newly-activated text input outside of the scroll view */
@property (nonatomic, weak) UIView *firstResponderViewOutsideScrollView;

// NOTE: currently these event props are only declared so we can export the
// event names to JS - we don't call the blocks directly because scroll events
Expand Down
6 changes: 6 additions & 0 deletions packages/react-native/React/Views/ScrollView/RCTScrollView.m
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,12 @@ - (void)_keyboardWillChangeFrame:(NSNotification *)notification
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 {
UIView *inputAccessoryView = _firstResponderViewOutsideScrollView.inputAccessoryView;
if (inputAccessoryView) {
// Text input view is within the inputAccessoryView.
contentDiff = endFrame.origin.y - beginFrame.origin.y;
}
}
} else if (endFrame.origin.y <= beginFrame.origin.y) {
// Keyboard opened for other reason
Expand Down

0 comments on commit 08976e4

Please sign in to comment.