From 4716d2c643a29fc77b871ca8555d8d78cb4ac427 Mon Sep 17 00:00:00 2001 From: Hailey Date: Mon, 2 Dec 2024 19:27:41 -0800 Subject: [PATCH] add to rn patch --- patches/react-native+0.76.3.patch | 181 ++++++++++++++++++++++++++++-- 1 file changed, 173 insertions(+), 8 deletions(-) diff --git a/patches/react-native+0.76.3.patch b/patches/react-native+0.76.3.patch index 9d64061c84..55ced573e1 100644 --- a/patches/react-native+0.76.3.patch +++ b/patches/react-native+0.76.3.patch @@ -12,7 +12,7 @@ index 62f52a7..ca30165 100644 filter?: ReadonlyArray | string | undefined; + transformOrigin?: string | (string | number)[] | undefined; } - + export type FontVariant = @@ -536,7 +537,11 @@ export interface TextStyle extends TextStyleIOS, TextStyleAndroid, ViewStyle { textShadowOffset?: {width: number; height: number} | undefined; @@ -25,7 +25,7 @@ index 62f52a7..ca30165 100644 + filter?: ReadonlyArray | string | undefined; + transformOrigin?: string | (string | number)[] | undefined; } - + /** @@ -558,5 +563,8 @@ export interface ImageStyle extends FlexStyle, ShadowStyleIOS, TransformsStyle { tintColor?: ColorValue | undefined; @@ -48,7 +48,7 @@ index e9b330f..ec5f58c 100644 +@property (nonatomic, copy) UIColor *customTintColor; + +- (void)forwarderBeginRefreshing; - + @end diff --git a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.m b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.m index 53bfd04..ff1b1ed 100644 @@ -60,12 +60,12 @@ index 53bfd04..ff1b1ed 100644 BOOL _hasMovedToWindow; + UIColor *_customTintColor; } - + - (instancetype)init @@ -58,6 +59,12 @@ - (void)layoutSubviews _isInitialRender = false; } - + +- (void)didMoveToSuperview +{ + [super didMoveToSuperview]; @@ -78,7 +78,7 @@ index 53bfd04..ff1b1ed 100644 @@ -221,4 +228,50 @@ - (void)refreshControlValueChanged } } - + +// Fix for https://github.com/facebook/react-native/issues/43388 +// A bug in iOS 17.4 causes the haptic to not play when refreshing if the tintColor +// is set before the refresh control gets added to the scrollview. We'll call this @@ -131,16 +131,181 @@ index 40aaf9c..1c60164 100644 --- a/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 - + RCT_EXPORT_VIEW_PROPERTY(onRefresh, RCTDirectEventBlock) RCT_EXPORT_VIEW_PROPERTY(refreshing, BOOL) -RCT_EXPORT_VIEW_PROPERTY(tintColor, UIColor) RCT_EXPORT_VIEW_PROPERTY(title, NSString) RCT_EXPORT_VIEW_PROPERTY(titleColor, UIColor) RCT_EXPORT_VIEW_PROPERTY(progressViewOffset, CGFloat) - + +RCT_REMAP_VIEW_PROPERTY(tintColor, customTintColor, UIColor) + RCT_EXPORT_METHOD(setNativeRefreshing : (nonnull NSNumber *)viewTag toRefreshing : (BOOL)refreshing) { [self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary *viewRegistry) { +diff --git a/node_modules/react-native/React/Views/ScrollView/RCTScrollView.m b/node_modules/react-native/React/Views/ScrollView/RCTScrollView.m +index e9ce48c..c0e057d 100644 +--- a/node_modules/react-native/React/Views/ScrollView/RCTScrollView.m ++++ b/node_modules/react-native/React/Views/ScrollView/RCTScrollView.m +@@ -159,26 +159,8 @@ - (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")); +@@ -338,6 +320,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 +@@ -427,6 +415,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 +437,8 @@ - (void)insertReactSubview:(UIView *)view atIndex:(NSInteger)atIndex + RCTApplyTransformationAccordingLayoutDirection(_contentView, self.reactLayoutDirection); + [_scrollView addSubview:view]; + } ++ ++ [self centerContentIfNeeded]; + } + + - (void)removeReactSubview:(UIView *)subview +@@ -594,6 +589,9 @@ - (void)scrollToOffset:(CGPoint)offset animated:(BOOL)animated + offset = CGPointMake(x, y); + } + [_scrollView setContentOffset:offset animated:animated]; ++ if (animated) { ++ [self sendScrollEventWithName:@"onMomentumScrollBegin" scrollView:_scrollView userData:nil]; ++ } + } + } + +@@ -616,6 +614,9 @@ - (void)scrollToEnd:(BOOL)animated + // Ensure at least one scroll event will fire + _allowNextScrollNoMatterWhat = YES; + [_scrollView setContentOffset:offset animated:animated]; ++ if (animated) { ++ [self sendScrollEventWithName:@"onMomentumScrollBegin" scrollView:_scrollView userData:nil]; ++ } + } + } + +@@ -652,9 +653,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. ++ * This implementation is based on https://petersteinberger.com/blog/2013/how-to-center-uiscrollview/. ++ */ ++-(void)centerContentIfNeeded ++{ ++ if (!_scrollView.centerContent) { ++ return; ++ } ++ ++ CGSize contentSize = self.contentSize; ++ CGSize boundsSize = self.bounds.size; ++ if (CGSizeEqualToSize(contentSize, CGSizeZero) || ++ CGSizeEqualToSize(boundsSize, CGSizeZero)) { ++ return; ++ } ++ ++ CGFloat top = 0, left = 0; ++ if (contentSize.width < boundsSize.width) { ++ left = (boundsSize.width - contentSize.width) * 0.5f; ++ } ++ if (contentSize.height < boundsSize.height) { ++ top = (boundsSize.height - contentSize.height) * 0.5f; ++ } ++ _scrollView.contentInset = UIEdgeInsetsMake(top, left, top, left); ++} ++ + - (void)addScrollListener:(NSObject *)scrollListener + { + [_scrollListeners addObject:scrollListener]; +@@ -933,6 +971,7 @@ - (void)updateContentSizeIfNeeded + CGSize contentSize = self.contentSize; + if (!CGSizeEqualToSize(_scrollView.contentSize, contentSize)) { + _scrollView.contentSize = contentSize; ++ [self centerContentIfNeeded]; + } + } + +@@ -1055,6 +1094,23 @@ -(type)getter \ + RCT_SET_AND_PRESERVE_OFFSET(setShowsVerticalScrollIndicator, showsVerticalScrollIndicator, BOOL) + RCT_SET_AND_PRESERVE_OFFSET(setZoomScale, zoomScale, CGFloat); + ++- (void)setScrollIndicatorInsets:(UIEdgeInsets)value ++{ ++ [_scrollView setScrollIndicatorInsets:value]; ++} ++ ++- (UIEdgeInsets)scrollIndicatorInsets ++{ ++ UIEdgeInsets verticalScrollIndicatorInsets = [_scrollView verticalScrollIndicatorInsets]; ++ UIEdgeInsets horizontalScrollIndicatorInsets = [_scrollView horizontalScrollIndicatorInsets]; ++ ++ return UIEdgeInsetsMake( ++ verticalScrollIndicatorInsets.top, ++ horizontalScrollIndicatorInsets.left, ++ verticalScrollIndicatorInsets.bottom, ++ horizontalScrollIndicatorInsets.right); ++} ++ + - (void)setAutomaticallyAdjustsScrollIndicatorInsets:(BOOL)automaticallyAdjusts API_AVAILABLE(ios(13.0)) + { + // `automaticallyAdjustsScrollIndicatorInsets` is available since iOS 13.