Skip to content

Commit

Permalink
Back out "Feature: ScrollView automaticallyAdjustKeyboardInsets"
Browse files Browse the repository at this point in the history
Summary:
Original commit changeset: 9ccfb4b6d477 / D30015799 (6e903b0)

The diff caused a redbox/error in some products. Reverting now and will try it again.

Changelog: Backing out PR: 31402

Differential Revision: D31238961

fbshipit-source-id: b2ccd3d3ab9d7e764e41fb54d8a7e60882d1405f
  • Loading branch information
sota000 authored and facebook-github-bot committed Sep 28, 2021
1 parent 2254d95 commit 8595f3f
Show file tree
Hide file tree
Showing 6 changed files with 21 additions and 116 deletions.
6 changes: 0 additions & 6 deletions Libraries/Components/ScrollView/ScrollView.js
Original file line number Diff line number Diff line change
Expand Up @@ -171,12 +171,6 @@ type IOSProps = $ReadOnly<{|
* @platform ios
*/
automaticallyAdjustContentInsets?: ?boolean,
/**
* Controls whether the ScrollView should automatically adjust it's contentInset
* and scrollViewInsets when the Keyboard changes it's size. The default value is false.
* @platform ios
*/
automaticallyAdjustKeyboardInsets?: ?boolean,
/**
* Controls whether iOS should automatically adjust the scroll indicator
* insets. The default value is true. Available on iOS 13 and later.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ export type ScrollViewNativeProps = $ReadOnly<{
alwaysBounceHorizontal?: ?boolean,
alwaysBounceVertical?: ?boolean,
automaticallyAdjustContentInsets?: ?boolean,
automaticallyAdjustKeyboardInsets?: ?boolean,
automaticallyAdjustsScrollIndicatorInsets?: ?boolean,
bounces?: ?boolean,
bouncesZoom?: ?boolean,
Expand Down
1 change: 0 additions & 1 deletion Libraries/Components/ScrollView/ScrollViewViewConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ const ScrollViewViewConfig = {
alwaysBounceHorizontal: true,
alwaysBounceVertical: true,
automaticallyAdjustContentInsets: true,
automaticallyAdjustKeyboardInsets: true,
automaticallyAdjustsScrollIndicatorInsets: true,
bounces: true,
bouncesZoom: true,
Expand Down
1 change: 0 additions & 1 deletion React/Views/ScrollView/RCTScrollView.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@

@property (nonatomic, assign) UIEdgeInsets contentInset;
@property (nonatomic, assign) BOOL automaticallyAdjustContentInsets;
@property (nonatomic, assign) BOOL automaticallyAdjustKeyboardInsets;
@property (nonatomic, assign) BOOL DEPRECATED_sendUpdatedChildFrames;
@property (nonatomic, assign) NSTimeInterval scrollEventThrottle;
@property (nonatomic, assign) BOOL centerContent;
Expand Down
127 changes: 21 additions & 106 deletions React/Views/ScrollView/RCTScrollView.m
Original file line number Diff line number Diff line change
Expand Up @@ -273,80 +273,11 @@ @implementation RCTScrollView {
NSHashTable *_scrollListeners;
}

- (void)registerKeyboardListener
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillChangeFrame:)
name:UIKeyboardWillChangeFrameNotification
object:nil];
}

- (void)unregisterKeyboardListener
{
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillChangeFrameNotification object: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;
}

- (void)keyboardWillChangeFrame:(NSNotification *)notification
{
if (![self automaticallyAdjustKeyboardInsets]) {
return;
}
if ([self isHorizontal:_scrollView]) {
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 = self.inverted ? absoluteViewOrigin.y : absoluteViewOrigin.y + self.bounds.size.height;

UIEdgeInsets newEdgeInsets = _scrollView.contentInset;
CGFloat inset = MAX(scrollViewLowerY - endFrame.origin.y, 0);
if (self.inverted) {
newEdgeInsets.top = MAX(inset, _contentInset.top);
} else {
newEdgeInsets.bottom = MAX(inset, _contentInset.bottom);
}

CGPoint newContentOffset = _scrollView.contentOffset;
CGFloat contentDiff = endFrame.origin.y - beginFrame.origin.y;
if (self.inverted) {
newContentOffset.y += contentDiff;
} else {
newContentOffset.y -= contentDiff;
}

[UIView animateWithDuration:duration
delay:0.0
options:animationOptionsWithCurve(curve)
animations:^{
self->_scrollView.contentInset = newEdgeInsets;
self->_scrollView.scrollIndicatorInsets = newEdgeInsets;
[self scrollToOffset:newContentOffset animated:NO];
}
completion:nil];
}

- (instancetype)initWithEventDispatcher:(id<RCTEventDispatcherProtocol>)eventDispatcher
{
RCTAssertParam(eventDispatcher);

if ((self = [super initWithFrame:CGRectZero])) {
[self registerKeyboardListener];
_eventDispatcher = eventDispatcher;

_scrollView = [[RCTCustomScrollView alloc] initWithFrame:CGRectZero];
Expand Down Expand Up @@ -467,7 +398,6 @@ - (void)dealloc
{
_scrollView.delegate = nil;
[_eventDispatcher.bridge.uiManager.observerCoordinator removeObserver:self];
[self unregisterKeyboardListener];
}

- (void)layoutSubviews
Expand Down Expand Up @@ -904,33 +834,23 @@ - (void)setMaintainVisibleContentPosition:(NSDictionary *)maintainVisibleContent
- (void)uiManagerWillPerformMounting:(RCTUIManager *)manager
{
RCTAssertUIManagerQueue();

[manager prependUIBlock:^(
__unused RCTUIManager *uiManager, __unused NSDictionary<NSNumber *, UIView *> *viewRegistry) {
BOOL horz = [self isHorizontal:self->_scrollView];
NSUInteger minIdx = [self->_maintainVisibleContentPosition[@"minIndexForVisible"] integerValue];
for (NSUInteger ii = minIdx; ii < self->_contentView.subviews.count; ++ii) {
// Find the first entirely visible view. This must be done after we update the content offset
// or it will tend to grab rows that were made visible by the shift in position
UIView *subview = self->_contentView.subviews[ii];
BOOL hasNewView = NO;
if (horz) {
CGFloat leftInset = self.inverted ? self->_scrollView.contentInset.right : self->_scrollView.contentInset.left;
CGFloat x = self->_scrollView.contentOffset.x + leftInset;
hasNewView = subview.frame.origin.x > x;
} else {
CGFloat bottomInset =
self.inverted ? self->_scrollView.contentInset.top : self->_scrollView.contentInset.bottom;
CGFloat y = self->_scrollView.contentOffset.y + bottomInset;
hasNewView = subview.frame.origin.y > y;
}
if (hasNewView || ii == self->_contentView.subviews.count - 1) {
self->_prevFirstVisibleFrame = subview.frame;
self->_firstVisibleView = subview;
break;
}
}
}];
[manager
prependUIBlock:^(__unused RCTUIManager *uiManager, __unused NSDictionary<NSNumber *, UIView *> *viewRegistry) {
BOOL horz = [self isHorizontal:self->_scrollView];
NSUInteger minIdx = [self->_maintainVisibleContentPosition[@"minIndexForVisible"] integerValue];
for (NSUInteger ii = minIdx; ii < self->_contentView.subviews.count; ++ii) {
// Find the first entirely visible view. This must be done after we update the content offset
// or it will tend to grab rows that were made visible by the shift in position
UIView *subview = self->_contentView.subviews[ii];
if ((horz ? subview.frame.origin.x >= self->_scrollView.contentOffset.x
: subview.frame.origin.y >= self->_scrollView.contentOffset.y) ||
ii == self->_contentView.subviews.count - 1) {
self->_prevFirstVisibleFrame = subview.frame;
self->_firstVisibleView = subview;
break;
}
}
}];
[manager addUIBlock:^(__unused RCTUIManager *uiManager, __unused NSDictionary<NSNumber *, UIView *> *viewRegistry) {
if (self->_maintainVisibleContentPosition == nil) {
return; // The prop might have changed in the previous UIBlocks, so need to abort here.
Expand All @@ -940,30 +860,25 @@ - (void)uiManagerWillPerformMounting:(RCTUIManager *)manager
if ([self isHorizontal:self->_scrollView]) {
CGFloat deltaX = self->_firstVisibleView.frame.origin.x - self->_prevFirstVisibleFrame.origin.x;
if (ABS(deltaX) > 0.1) {
CGFloat leftInset = self.inverted ? self->_scrollView.contentInset.right : self->_scrollView.contentInset.left;
CGFloat x = self->_scrollView.contentOffset.x + leftInset;
self->_scrollView.contentOffset =
CGPointMake(self->_scrollView.contentOffset.x + deltaX, self->_scrollView.contentOffset.y);
if (autoscrollThreshold != nil) {
// If the offset WAS within the threshold of the start, animate to the start.
if (x - deltaX <= [autoscrollThreshold integerValue]) {
[self scrollToOffset:CGPointMake(-leftInset, self->_scrollView.contentOffset.y) animated:YES];
if (self->_scrollView.contentOffset.x - deltaX <= [autoscrollThreshold integerValue]) {
[self scrollToOffset:CGPointMake(0, self->_scrollView.contentOffset.y) animated:YES];
}
}
}
} else {
CGRect newFrame = self->_firstVisibleView.frame;
CGFloat deltaY = newFrame.origin.y - self->_prevFirstVisibleFrame.origin.y;
if (ABS(deltaY) > 0.1) {
CGFloat bottomInset =
self.inverted ? self->_scrollView.contentInset.top : self->_scrollView.contentInset.bottom;
CGFloat y = self->_scrollView.contentOffset.y + bottomInset;
self->_scrollView.contentOffset =
CGPointMake(self->_scrollView.contentOffset.x, self->_scrollView.contentOffset.y + deltaY);
if (autoscrollThreshold != nil) {
// If the offset WAS within the threshold of the start, animate to the start.
if (y - deltaY <= [autoscrollThreshold integerValue]) {
[self scrollToOffset:CGPointMake(self->_scrollView.contentOffset.x, -bottomInset) animated:YES];
if (self->_scrollView.contentOffset.y - deltaY <= [autoscrollThreshold integerValue]) {
[self scrollToOffset:CGPointMake(self->_scrollView.contentOffset.x, 0) animated:YES];
}
}
}
Expand Down
1 change: 0 additions & 1 deletion React/Views/ScrollView/RCTScrollViewManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ - (UIView *)view
RCT_EXPORT_VIEW_PROPERTY(centerContent, BOOL)
RCT_EXPORT_VIEW_PROPERTY(maintainVisibleContentPosition, NSDictionary)
RCT_EXPORT_VIEW_PROPERTY(automaticallyAdjustContentInsets, BOOL)
RCT_EXPORT_VIEW_PROPERTY(automaticallyAdjustKeyboardInsets, BOOL)
RCT_EXPORT_VIEW_PROPERTY(decelerationRate, CGFloat)
RCT_EXPORT_VIEW_PROPERTY(directionalLockEnabled, BOOL)
RCT_EXPORT_VIEW_PROPERTY(indicatorStyle, UIScrollViewIndicatorStyle)
Expand Down

1 comment on commit 8595f3f

@AndreiCalazans
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👀 @mrousavy

Please sign in to comment.