Skip to content

Commit 1771553

Browse files
authored
fix(android): dead state after rapid present/dismiss (#593)
* fix(android,ios): dead state after rapid present/dismiss (#590) * docs: update changelog for #593
1 parent 1e4a8cf commit 1771553

6 files changed

Lines changed: 40 additions & 28 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
### 🐛 Bug fixes
1111

1212
- **iOS**: Fixed keyboard scroll positioning when sheet auto-expands from a smaller detent. ([#592](https://github.com/lodev09/react-native-true-sheet/pull/592) by [@lodev09](https://github.com/lodev09))
13+
- **Android**: Fixed dead state after rapid present/dismiss cycles. ([#593](https://github.com/lodev09/react-native-true-sheet/pull/593) by [@lodev09](https://github.com/lodev09))
1314
- **iOS**: Fixed position change not emitting when detent or index changed. ([#584](https://github.com/lodev09/react-native-true-sheet/pull/584) by [@lodev09](https://github.com/lodev09))
1415
- **Android**: Use RN `BackHandler` for back press detection for reliability across Android versions. ([#580](https://github.com/lodev09/react-native-true-sheet/pull/580) by [@lodev09](https://github.com/lodev09))
1516

android/src/main/java/com/lodev09/truesheet/TrueSheetView.kt

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,6 @@ class TrueSheetView(private val reactContext: ThemedReactContext) :
119119

120120
if (child is TrueSheetContainerView) {
121121
child.delegate = this
122-
viewController.createSheet()
123-
setupScrollable()
124-
125122
val surfaceId = UIManagerHelper.getSurfaceId(this)
126123
eventDispatcher?.dispatchEvent(MountEvent(surfaceId, id))
127124
}
@@ -349,11 +346,8 @@ class TrueSheetView(private val reactContext: ThemedReactContext) :
349346
return
350347
}
351348

352-
if (viewController.coordinatorLayout == null || viewController.sheetView == null) {
353-
RNLog.w(reactContext, "TrueSheet: sheet is not ready. Ensure it is mounted before presenting.")
354-
promiseCallback()
355-
return
356-
}
349+
viewController.createSheet()
350+
setupScrollable()
357351

358352
// Dismiss keyboard if focused view is within a sheet or if target detent will be dimmed
359353
val parentSheet = TrueSheetStackManager.getTopmostSheet()

example/shared/src/components/Button.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@ import { BUTTON_HEIGHT, DARK_BLUE, SPACING } from '../utils';
44

55
interface ButtonProps extends PressableProps {
66
text: string;
7+
hint?: string;
78
loading?: boolean;
89
}
910

1011
export const Button = (props: ButtonProps) => {
11-
const { text, style, loading, ...rest } = props;
12+
const { text, hint, style, loading, ...rest } = props;
1213
return (
1314
<Pressable
1415
style={(state) => [
@@ -19,6 +20,7 @@ export const Button = (props: ButtonProps) => {
1920
{...rest}
2021
>
2122
<Text style={styles.text}>{text}</Text>
23+
{hint && <Text style={styles.hint}>{hint}</Text>}
2224
{loading && <ActivityIndicator style={styles.loader} size="small" color="#fff" />}
2325
</Pressable>
2426
);
@@ -39,6 +41,10 @@ const styles = StyleSheet.create({
3941
text: {
4042
color: '#fff',
4143
},
44+
hint: {
45+
fontSize: 10,
46+
color: 'rgba(255, 255, 255, 0.5)',
47+
},
4248
loader: {
4349
position: 'absolute',
4450
right: SPACING,

example/shared/src/components/sheets/FlatListSheet.tsx

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,7 @@ export const FlatListSheet = forwardRef<TrueSheet, FlatListSheetProps>((props, r
2828
</Header>
2929
}
3030
onDidDismiss={() => console.log('Sheet FlatList dismissed!')}
31-
onDidPresent={() => {
32-
console.log(`Sheet FlatList presented!`);
33-
scrollRef.current?.scrollToOffset({ offset: 99999, animated: true });
34-
}}
31+
onDidPresent={() => console.log(`Sheet FlatList presented!`)}
3532
footer={<Footer text="OPEN BLANK SHEET" onPress={() => testRef.current?.present()} />}
3633
{...props}
3734
>

example/shared/src/screens/MapScreen.tsx

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,14 @@ const MapScreenInner = ({
7878
console.log('basic sheet presented');
7979
};
8080

81+
const rapidPresentDismiss = async () => {
82+
for (let i = 0; i < 5; i++) {
83+
await basicSheet.current?.present(0);
84+
await basicSheet.current?.dismiss();
85+
}
86+
await basicSheet.current?.present(0);
87+
};
88+
8189
const presentScrollViewSheet = () => {
8290
setScrollViewLoading(true);
8391
requestAnimationFrame(async () => {
@@ -166,7 +174,12 @@ const MapScreenInner = ({
166174
<Text style={styles.title}>True Sheet</Text>
167175
<Text style={styles.subtitle}>The true native bottom sheet experience.</Text>
168176
</View>
169-
<Button text="TrueSheet View" onPress={() => presentBasicSheet(0)} />
177+
<Button
178+
text="TrueSheet View"
179+
hint="Long press to stress test"
180+
onPress={() => presentBasicSheet(0)}
181+
onLongPress={rapidPresentDismiss}
182+
/>
170183
<Button text="Open Modal" onPress={onNavigateToModal} />
171184
<Button text="Sheet Navigator" onPress={onNavigateToSheetStack} />
172185
{isTablet && (

ios/TrueSheetView.mm

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -261,11 +261,7 @@ - (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &
261261
_insetAdjustment = (NSInteger)newProps.insetAdjustment;
262262
_controller.insetAdjustment = _insetAdjustment;
263263

264-
if (_containerView) {
265-
_containerView.scrollableEnabled = _scrollable;
266-
_containerView.insetAdjustment = _insetAdjustment;
267-
_containerView.scrollableOptions = _scrollableOptions;
268-
}
264+
[self setupScrollable];
269265
}
270266

271267
- (void)updateState:(const State::Shared &)state oldState:(const State::Shared &)oldState {
@@ -314,9 +310,7 @@ - (void)finalizeUpdates:(RNComponentViewUpdateMask)updateMask {
314310
if (!(updateMask & RNComponentViewUpdateMaskProps) || !_controller)
315311
return;
316312

317-
if (_containerView) {
318-
[_containerView setupScrollable];
319-
}
313+
[self setupScrollable];
320314

321315
if (_controller.isPresented) {
322316
[self applySheetPropsUpdate];
@@ -384,11 +378,6 @@ - (void)mountChildComponentView:(UIView<RCTComponentViewProtocol> *)childCompone
384378
_controller.headerHeight = @(headerHeight);
385379
}
386380

387-
_containerView.scrollableEnabled = _scrollable;
388-
_containerView.insetAdjustment = _insetAdjustment;
389-
_containerView.scrollableOptions = _scrollableOptions;
390-
[_containerView setupScrollable];
391-
392381
if (_eventEmitter) {
393382
[TrueSheetLifecycleEvents emitMount:_eventEmitter];
394383
} else {
@@ -449,6 +438,8 @@ - (void)presentAtIndex:(NSInteger)index
449438
[_controller setupSheetDetents];
450439
[_controller setupActiveDetentWithIndex:index];
451440

441+
[self setupScrollable];
442+
452443
[_screensEventObserver capturePresenterScreenFromView:self];
453444
[_screensEventObserver startObservingWithState:_state.get()->getData()];
454445

@@ -575,7 +566,7 @@ - (void)containerViewHeaderDidChangeSize:(CGSize)newSize {
575566

576567
// When the ScrollView changes (e.g. conditional remount), re-pin the new ScrollView.
577568
- (void)containerViewScrollViewDidChange {
578-
[_containerView setupScrollable];
569+
[self setupScrollable];
579570
}
580571

581572
#pragma mark - TrueSheetViewControllerDelegate
@@ -697,6 +688,16 @@ - (void)presenterScreenWillAppear {
697688

698689
#pragma mark - Private Helpers
699690

691+
- (void)setupScrollable {
692+
if (!_containerView)
693+
return;
694+
695+
_containerView.scrollableEnabled = _scrollable;
696+
_containerView.insetAdjustment = _insetAdjustment;
697+
_containerView.scrollableOptions = _scrollableOptions;
698+
[_containerView setupScrollable];
699+
}
700+
700701
- (void)applySheetPropsUpdate {
701702
BOOL pendingLayoutUpdate = _pendingLayoutUpdate;
702703
_pendingLayoutUpdate = NO;

0 commit comments

Comments
 (0)