Patch RCTScrollView to fix centerContent (#6298)
This commit is contained in:
@@ -9,7 +9,7 @@ index caa5540..c5d4e67 100644
|
|||||||
- type != nil && [type length] > 0 ? type : @"application/octet-stream",
|
- type != nil && [type length] > 0 ? type : @"application/octet-stream",
|
||||||
+ ![type isEqual:[NSNull null]] && [type length] > 0 ? type : @"application/octet-stream",
|
+ ![type isEqual:[NSNull null]] && [type length] > 0 ? type : @"application/octet-stream",
|
||||||
[data base64EncodedStringWithOptions:0]];
|
[data base64EncodedStringWithOptions:0]];
|
||||||
|
|
||||||
resolve(text);
|
resolve(text);
|
||||||
diff --git a/node_modules/react-native/Libraries/Text/TextInput/RCTBaseTextInputView.mm b/node_modules/react-native/Libraries/Text/TextInput/RCTBaseTextInputView.mm
|
diff --git a/node_modules/react-native/Libraries/Text/TextInput/RCTBaseTextInputView.mm b/node_modules/react-native/Libraries/Text/TextInput/RCTBaseTextInputView.mm
|
||||||
index b0d71dc..41b9a0e 100644
|
index b0d71dc..41b9a0e 100644
|
||||||
@@ -18,7 +18,7 @@ index b0d71dc..41b9a0e 100644
|
|||||||
@@ -377,10 +377,6 @@ - (void)textInputDidBeginEditing
|
@@ -377,10 +377,6 @@ - (void)textInputDidBeginEditing
|
||||||
self.backedTextInputView.attributedText = [NSAttributedString new];
|
self.backedTextInputView.attributedText = [NSAttributedString new];
|
||||||
}
|
}
|
||||||
|
|
||||||
- if (_selectTextOnFocus) {
|
- if (_selectTextOnFocus) {
|
||||||
- [self.backedTextInputView selectAll:nil];
|
- [self.backedTextInputView selectAll:nil];
|
||||||
- }
|
- }
|
||||||
@@ -35,7 +35,7 @@ index b0d71dc..41b9a0e 100644
|
|||||||
+ [self.backedTextInputView selectAll:nil];
|
+ [self.backedTextInputView selectAll:nil];
|
||||||
+ }
|
+ }
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)reactBlur
|
- (void)reactBlur
|
||||||
diff --git a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.h b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.h
|
diff --git a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.h b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.h
|
||||||
index e9b330f..ec5f58c 100644
|
index e9b330f..ec5f58c 100644
|
||||||
@@ -48,10 +48,10 @@ index e9b330f..ec5f58c 100644
|
|||||||
+@property (nonatomic, copy) UIColor *customTintColor;
|
+@property (nonatomic, copy) UIColor *customTintColor;
|
||||||
+
|
+
|
||||||
+- (void)forwarderBeginRefreshing;
|
+- (void)forwarderBeginRefreshing;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
diff --git a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.m b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.m
|
diff --git a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.m b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.m
|
||||||
index b09e653..288e60c 100644
|
index b09e653..d2b4e05 100644
|
||||||
--- a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.m
|
--- a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.m
|
||||||
+++ b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.m
|
+++ b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.m
|
||||||
@@ -22,6 +22,7 @@ @implementation RCTRefreshControl {
|
@@ -22,6 +22,7 @@ @implementation RCTRefreshControl {
|
||||||
@@ -60,12 +60,12 @@ index b09e653..288e60c 100644
|
|||||||
CGFloat _progressViewOffset;
|
CGFloat _progressViewOffset;
|
||||||
+ UIColor *_customTintColor;
|
+ UIColor *_customTintColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (instancetype)init
|
- (instancetype)init
|
||||||
@@ -56,6 +57,12 @@ - (void)layoutSubviews
|
@@ -56,6 +57,12 @@ - (void)layoutSubviews
|
||||||
_isInitialRender = false;
|
_isInitialRender = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
+- (void)didMoveToSuperview
|
+- (void)didMoveToSuperview
|
||||||
+{
|
+{
|
||||||
+ [super didMoveToSuperview];
|
+ [super didMoveToSuperview];
|
||||||
@@ -78,7 +78,7 @@ index b09e653..288e60c 100644
|
|||||||
@@ -203,4 +210,58 @@ - (void)refreshControlValueChanged
|
@@ -203,4 +210,58 @@ - (void)refreshControlValueChanged
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
+- (void)setCustomTintColor:(UIColor *)customTintColor
|
+- (void)setCustomTintColor:(UIColor *)customTintColor
|
||||||
+{
|
+{
|
||||||
+ _customTintColor = customTintColor;
|
+ _customTintColor = customTintColor;
|
||||||
@@ -139,26 +139,139 @@ index 40aaf9c..1c60164 100644
|
|||||||
--- a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControlManager.m
|
--- a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControlManager.m
|
||||||
+++ b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControlManager.m
|
+++ b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControlManager.m
|
||||||
@@ -22,11 +22,12 @@ - (UIView *)view
|
@@ -22,11 +22,12 @@ - (UIView *)view
|
||||||
|
|
||||||
RCT_EXPORT_VIEW_PROPERTY(onRefresh, RCTDirectEventBlock)
|
RCT_EXPORT_VIEW_PROPERTY(onRefresh, RCTDirectEventBlock)
|
||||||
RCT_EXPORT_VIEW_PROPERTY(refreshing, BOOL)
|
RCT_EXPORT_VIEW_PROPERTY(refreshing, BOOL)
|
||||||
-RCT_EXPORT_VIEW_PROPERTY(tintColor, UIColor)
|
-RCT_EXPORT_VIEW_PROPERTY(tintColor, UIColor)
|
||||||
RCT_EXPORT_VIEW_PROPERTY(title, NSString)
|
RCT_EXPORT_VIEW_PROPERTY(title, NSString)
|
||||||
RCT_EXPORT_VIEW_PROPERTY(titleColor, UIColor)
|
RCT_EXPORT_VIEW_PROPERTY(titleColor, UIColor)
|
||||||
RCT_EXPORT_VIEW_PROPERTY(progressViewOffset, CGFloat)
|
RCT_EXPORT_VIEW_PROPERTY(progressViewOffset, CGFloat)
|
||||||
|
|
||||||
+RCT_REMAP_VIEW_PROPERTY(tintColor, customTintColor, UIColor)
|
+RCT_REMAP_VIEW_PROPERTY(tintColor, customTintColor, UIColor)
|
||||||
+
|
+
|
||||||
RCT_EXPORT_METHOD(setNativeRefreshing : (nonnull NSNumber *)viewTag toRefreshing : (BOOL)refreshing)
|
RCT_EXPORT_METHOD(setNativeRefreshing : (nonnull NSNumber *)viewTag toRefreshing : (BOOL)refreshing)
|
||||||
{
|
{
|
||||||
[self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
|
[self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
|
||||||
|
diff --git a/node_modules/react-native/React/Views/ScrollView/RCTScrollView.m b/node_modules/react-native/React/Views/ScrollView/RCTScrollView.m
|
||||||
|
index 1aead51..39e6244 100644
|
||||||
|
--- a/node_modules/react-native/React/Views/ScrollView/RCTScrollView.m
|
||||||
|
+++ b/node_modules/react-native/React/Views/ScrollView/RCTScrollView.m
|
||||||
|
@@ -159,31 +159,6 @@ - (BOOL)touchesShouldCancelInContentView:(__unused UIView *)view
|
||||||
|
return !shouldDisableScrollInteraction;
|
||||||
|
}
|
||||||
|
|
||||||
|
-/*
|
||||||
|
- * Automatically centers the content such that if the content is smaller than the
|
||||||
|
- * ScrollView, we force it to be centered, but when you zoom or the content otherwise
|
||||||
|
- * becomes larger than the ScrollView, there is no padding around the content but it
|
||||||
|
- * can still fill the whole view.
|
||||||
|
- */
|
||||||
|
-- (void)setContentOffset:(CGPoint)contentOffset
|
||||||
|
-{
|
||||||
|
- UIView *contentView = [self contentView];
|
||||||
|
- if (contentView && _centerContent && !CGSizeEqualToSize(contentView.frame.size, CGSizeZero)) {
|
||||||
|
- CGSize subviewSize = contentView.frame.size;
|
||||||
|
- CGSize scrollViewSize = self.bounds.size;
|
||||||
|
- if (subviewSize.width <= scrollViewSize.width) {
|
||||||
|
- contentOffset.x = -(scrollViewSize.width - subviewSize.width) / 2.0;
|
||||||
|
- }
|
||||||
|
- if (subviewSize.height <= scrollViewSize.height) {
|
||||||
|
- contentOffset.y = -(scrollViewSize.height - subviewSize.height) / 2.0;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- super.contentOffset = CGPointMake(
|
||||||
|
- RCTSanitizeNaNValue(contentOffset.x, @"scrollView.contentOffset.x"),
|
||||||
|
- RCTSanitizeNaNValue(contentOffset.y, @"scrollView.contentOffset.y"));
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
- (void)setFrame:(CGRect)frame
|
||||||
|
{
|
||||||
|
// Preserving and revalidating `contentOffset`.
|
||||||
|
@@ -427,6 +402,11 @@ - (void)setRemoveClippedSubviews:(__unused BOOL)removeClippedSubviews
|
||||||
|
// Does nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
+- (void)setFrame:(CGRect)frame {
|
||||||
|
+ [super setFrame:frame];
|
||||||
|
+ [self centerContentIfNeeded];
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
- (void)insertReactSubview:(UIView *)view atIndex:(NSInteger)atIndex
|
||||||
|
{
|
||||||
|
[super insertReactSubview:view atIndex:atIndex];
|
||||||
|
@@ -444,6 +424,8 @@ - (void)insertReactSubview:(UIView *)view atIndex:(NSInteger)atIndex
|
||||||
|
RCTApplyTransformationAccordingLayoutDirection(_contentView, self.reactLayoutDirection);
|
||||||
|
[_scrollView addSubview:view];
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ [self centerContentIfNeeded];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)removeReactSubview:(UIView *)subview
|
||||||
|
@@ -652,9 +634,46 @@ -(void)delegateMethod : (UIScrollView *)scrollView \
|
||||||
|
}
|
||||||
|
|
||||||
|
RCT_SCROLL_EVENT_HANDLER(scrollViewWillBeginDecelerating, onMomentumScrollBegin)
|
||||||
|
-RCT_SCROLL_EVENT_HANDLER(scrollViewDidZoom, onScroll)
|
||||||
|
RCT_SCROLL_EVENT_HANDLER(scrollViewDidScrollToTop, onScrollToTop)
|
||||||
|
|
||||||
|
+-(void)scrollViewDidZoom : (UIScrollView *)scrollView
|
||||||
|
+{
|
||||||
|
+ [self centerContentIfNeeded];
|
||||||
|
+
|
||||||
|
+ RCT_SEND_SCROLL_EVENT(onScroll, nil);
|
||||||
|
+ RCT_FORWARD_SCROLL_EVENT(scrollViewDidZoom : scrollView);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Automatically centers the content such that if the content is smaller than the
|
||||||
|
+ * ScrollView, we force it to be centered, but when you zoom or the content otherwise
|
||||||
|
+ * becomes larger than the ScrollView, there is no padding around the content but it
|
||||||
|
+ * can still fill the whole view.
|
||||||
|
+ *
|
||||||
|
+ * PATCHED: This deviates from the original React Native implementation to fix two issues:
|
||||||
|
+ *
|
||||||
|
+ * - The scroll view was swallowing any taps immediately after pinching
|
||||||
|
+ * - The scroll view was jittering when crossing the full screen threshold while pinching
|
||||||
|
+ *
|
||||||
|
+ * This implementation is based on https://petersteinberger.com/blog/2013/how-to-center-uiscrollview/.
|
||||||
|
+ */
|
||||||
|
+-(void)centerContentIfNeeded
|
||||||
|
+{
|
||||||
|
+ if (_scrollView.centerContent &&
|
||||||
|
+ !CGSizeEqualToSize(self.contentSize, CGSizeZero) &&
|
||||||
|
+ !CGSizeEqualToSize(self.bounds.size, CGSizeZero)
|
||||||
|
+ ) {
|
||||||
|
+ CGFloat top = 0, left = 0;
|
||||||
|
+ if (self.contentSize.width < self.bounds.size.width) {
|
||||||
|
+ left = (self.bounds.size.width - self.contentSize.width) * 0.5f;
|
||||||
|
+ }
|
||||||
|
+ if (self.contentSize.height < self.bounds.size.height) {
|
||||||
|
+ top = (self.bounds.size.height - self.contentSize.height) * 0.5f;
|
||||||
|
+ }
|
||||||
|
+ _scrollView.contentInset = UIEdgeInsetsMake(top, left, top, left);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
- (void)addScrollListener:(NSObject<UIScrollViewDelegate> *)scrollListener
|
||||||
|
{
|
||||||
|
[_scrollListeners addObject:scrollListener];
|
||||||
|
@@ -913,6 +932,7 @@ - (void)updateContentSizeIfNeeded
|
||||||
|
CGSize contentSize = self.contentSize;
|
||||||
|
if (!CGSizeEqualToSize(_scrollView.contentSize, contentSize)) {
|
||||||
|
_scrollView.contentSize = contentSize;
|
||||||
|
+ [self centerContentIfNeeded];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
diff --git a/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/core/JavaTimerManager.java b/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/core/JavaTimerManager.java
|
diff --git a/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/core/JavaTimerManager.java b/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/core/JavaTimerManager.java
|
||||||
index 5f5e1ab..aac00b6 100644
|
index 5f5e1ab..aac00b6 100644
|
||||||
--- a/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/core/JavaTimerManager.java
|
--- a/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/core/JavaTimerManager.java
|
||||||
+++ b/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/core/JavaTimerManager.java
|
+++ b/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/core/JavaTimerManager.java
|
||||||
@@ -99,8 +99,9 @@ public class JavaTimerManager {
|
@@ -99,8 +99,9 @@ public class JavaTimerManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the JS thread is busy for multiple frames we cancel any other pending runnable.
|
// If the JS thread is busy for multiple frames we cancel any other pending runnable.
|
||||||
- if (mCurrentIdleCallbackRunnable != null) {
|
- if (mCurrentIdleCallbackRunnable != null) {
|
||||||
- mCurrentIdleCallbackRunnable.cancel();
|
- mCurrentIdleCallbackRunnable.cancel();
|
||||||
@@ -166,5 +279,5 @@ index 5f5e1ab..aac00b6 100644
|
|||||||
+ if (currentRunnable != null) {
|
+ if (currentRunnable != null) {
|
||||||
+ currentRunnable.cancel();
|
+ currentRunnable.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
mCurrentIdleCallbackRunnable = new IdleCallbackRunnable(frameTimeNanos);
|
mCurrentIdleCallbackRunnable = new IdleCallbackRunnable(frameTimeNanos);
|
||||||
|
|||||||
Reference in New Issue
Block a user