From 07e6d001a25825bb86ee6e9afcb65abacf9fadc4 Mon Sep 17 00:00:00 2001 From: Hailey Date: Tue, 19 Mar 2024 12:05:28 -0700 Subject: [PATCH] patch-fix `RCTRefreshControl` (#3259) --- patches/react-native+0.73.2.patch | 103 ++++----------------------- patches/react-native+0.73.2.patch.md | 8 +-- 2 files changed, 19 insertions(+), 92 deletions(-) diff --git a/patches/react-native+0.73.2.patch b/patches/react-native+0.73.2.patch index 8f100169..8db23da0 100644 --- a/patches/react-native+0.73.2.patch +++ b/patches/react-native+0.73.2.patch @@ -1,92 +1,19 @@ -diff --git a/node_modules/react-native/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.mm b/node_modules/react-native/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.mm -index 9dca6a5..090bda5 100644 ---- a/node_modules/react-native/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.mm -+++ b/node_modules/react-native/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.mm -@@ -266,11 +266,10 @@ - (void)textViewDidChange:(__unused UITextView *)textView +diff --git a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.m b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.m +index b09e653..d290dab 100644 +--- a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.m ++++ b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.m +@@ -198,6 +198,14 @@ - (void)refreshControlValueChanged + [self setCurrentRefreshingState:super.refreshing]; + _refreshingProgrammatically = NO; - - (void)textViewDidChangeSelection:(__unused UITextView *)textView - { -- if (_lastStringStateWasUpdatedWith && ![_lastStringStateWasUpdatedWith isEqual:_backedTextInputView.attributedText]) { -+ if (![_lastStringStateWasUpdatedWith isEqual:_backedTextInputView.attributedText]) { - [self textViewDidChange:_backedTextInputView]; - _ignoreNextTextInputCall = YES; - } -- _lastStringStateWasUpdatedWith = _backedTextInputView.attributedText; - [self textViewProbablyDidChangeSelection]; - } - -diff --git a/node_modules/react-native/Libraries/Text/TextInput/RCTBaseTextInputShadowView.mm b/node_modules/react-native/Libraries/Text/TextInput/RCTBaseTextInputShadowView.mm -index 1f06b79..ab458f3 100644 ---- a/node_modules/react-native/Libraries/Text/TextInput/RCTBaseTextInputShadowView.mm -+++ b/node_modules/react-native/Libraries/Text/TextInput/RCTBaseTextInputShadowView.mm -@@ -87,7 +87,7 @@ - (void)invalidateContentSize - return; - } - -- CGSize maximumSize = self.layoutMetrics.frame.size; -+ CGSize maximumSize = self.layoutMetrics.contentFrame.size; - - if (_maximumNumberOfLines == 1) { - maximumSize.width = CGFLOAT_MAX; -@@ -158,6 +158,8 @@ - (void)uiManagerWillPerformMounting - [attributedText insertAttributedString:propertyAttributedText atIndex:0]; - } - -+ [self postprocessAttributedText:attributedText]; -+ - NSAttributedString *newAttributedText; - if (![_previousAttributedText isEqualToAttributedString:attributedText]) { - // We have to follow `set prop` pattern: -@@ -191,6 +193,52 @@ - (void)uiManagerWillPerformMounting - }]; - } - -+- (void)postprocessAttributedText:(NSMutableAttributedString *)attributedText -+{ -+ __block CGFloat maximumLineHeight = 0; -+ -+ [attributedText enumerateAttribute:NSParagraphStyleAttributeName -+ inRange:NSMakeRange(0, attributedText.length) -+ options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired -+ usingBlock:^(NSParagraphStyle *paragraphStyle, __unused NSRange range, __unused BOOL *stop) { -+ if (!paragraphStyle) { -+ return; ++ if (@available(iOS 17.4, *)) { ++ if (_currentRefreshingState) { ++ UIImpactFeedbackGenerator *feedbackGenerator = [[UIImpactFeedbackGenerator alloc] initWithStyle:UIImpactFeedbackStyleLight]; ++ [feedbackGenerator prepare]; ++ [feedbackGenerator impactOccurred]; + } -+ -+ maximumLineHeight = MAX(paragraphStyle.maximumLineHeight, maximumLineHeight); -+ }]; -+ -+ if (maximumLineHeight == 0) { -+ // `lineHeight` was not specified, nothing to do. -+ return; + } + -+ __block CGFloat maximumFontLineHeight = 0; -+ -+ [attributedText enumerateAttribute:NSFontAttributeName -+ inRange:NSMakeRange(0, attributedText.length) -+ options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired -+ usingBlock:^(UIFont *font, NSRange range, __unused BOOL *stop) { -+ if (!font) { -+ return; -+ } -+ -+ if (maximumFontLineHeight <= font.lineHeight) { -+ maximumFontLineHeight = font.lineHeight; -+ } -+ }]; -+ -+ if (maximumLineHeight < maximumFontLineHeight) { -+ return; -+ } -+ -+ CGFloat baseLineOffset = maximumLineHeight / 2.0 - maximumFontLineHeight / 2.0; -+ -+ [attributedText addAttribute:NSBaselineOffsetAttributeName -+ value:@(baseLineOffset) -+ range:NSMakeRange(0, attributedText.length)]; -+} -+ - #pragma mark - - - - (NSAttributedString *)measurableAttributedText + if (_onRefresh) { + _onRefresh(nil); + } \ No newline at end of file diff --git a/patches/react-native+0.73.2.patch.md b/patches/react-native+0.73.2.patch.md index 3d327516..7f70baf2 100644 --- a/patches/react-native+0.73.2.patch.md +++ b/patches/react-native+0.73.2.patch.md @@ -1,5 +1,5 @@ -# TextInput Patch +# RefreshControl Patch -Patching `RCTBaseTextShadowInput.mm` from https://github.com/facebook/react-native/pull/38359. This fixes some text -getting cut off inside the composer. This was merged in December, so we should be able to remove this patch when RN -ships the next release. +Patching `RCTRefreshControl.mm` temporarily to play an impact haptic on refresh when using iOS 17.4 or higher. Since +17.4, there has been a regression somewhere causing haptics to not play on iOS on refresh. Should monitor for an update +in the RN repo: https://github.com/facebook/react-native/issues/43388 \ No newline at end of file