From 4281372bee42e22356f684031d2bba42bfe90562 Mon Sep 17 00:00:00 2001 From: Mohamed Boudra Date: Fri, 6 Nov 2026 15:14:23 +0700 Subject: [PATCH] fix(app): keep the chat readable with the keyboard open on iOS 26+ (#8918) iOS 26 adds a scroll edge effect, a blur at each edge of every scroll view, and places it in the scroll view's own coordinates without applying transforms. The keyboard lifts the chat with a translateY, so on iPhones the blur lands over the readable conversation and stays until the next scroll. The app draws its own header fade, so the app's ScrollView component class, which backs every React Native ScrollView, hides all four edge effects. Co-authored-by: David Greenspan <155814+dgreensp@users.noreply.github.com> --- .../ios/PaseoScrollViewComponentView.mm | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/packages/app/modules/paseo-scroll/ios/PaseoScrollViewComponentView.mm b/packages/app/modules/paseo-scroll/ios/PaseoScrollViewComponentView.mm index 6b9ca95435..4bd5cfe2f3 100644 --- a/packages/app/modules/paseo-scroll/ios/PaseoScrollViewComponentView.mm +++ b/packages/app/modules/paseo-scroll/ios/PaseoScrollViewComponentView.mm @@ -54,6 +54,28 @@ using namespace facebook::react; [[RCTComponentViewFactory currentComponentViewFactory] registerComponentViewClass:self]; } +// iOS 26 blurs a scroll view's edges and places the blur in the scroll view's own coordinates, +// ignoring transforms. The keyboard lifts the chat with a translateY, so on iPhones the blur lands +// over the readable chat and stays until the next scroll (#7883). React Native hides it for +// inverted lists for the same reason (https://github.com/react/react-native/pull/58684). The app +// draws its own header fade, so every edge is hidden; hiding only top and bottom leaves the side +// effects, which also cover a transformed list on device. +- (instancetype)initWithFrame:(CGRect)frame +{ + if (self = [super initWithFrame:frame]) { +#if defined(__IPHONE_26_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_26_0 + if (@available(iOS 26.0, *)) { + UIScrollView *scrollView = self.scrollView; + scrollView.topEdgeEffect.hidden = YES; + scrollView.bottomEdgeEffect.hidden = YES; + scrollView.leftEdgeEffect.hidden = YES; + scrollView.rightEdgeEffect.hidden = YES; + } +#endif + } + return self; +} + - (void)mountingTransactionWillMount:(const MountingTransaction &)transaction withSurfaceTelemetry:(const SurfaceTelemetry &)surfaceTelemetry {