Skip to content

Commit

Permalink
fix: update how toastWindow is obtained (#58)
Browse files Browse the repository at this point in the history
* fix: unbalanced calls to begin/end appearance transitions

* fix: update how toastWindow is obtained

see facebook/react-native#35716
  • Loading branch information
vonovak authored Aug 1, 2023
1 parent a62c66a commit 5b8defb
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 17 deletions.
21 changes: 13 additions & 8 deletions example/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ export default function App() {
style={{ backgroundColor: 'white' }}
>
<View style={styles.container}>
<Button
title={'simple toast'}
onPress={() => {
Toast.show('This is a toast.', Toast.SHORT);
}}
/>
<Button
onPress={() => {
setModalVisible(true);
Expand All @@ -59,15 +65,10 @@ export default function App() {
);
}, 500);
}}
title="Show Modal"
title="toast on top of Modal"
/>
{/*<Text>{JSON.stringify(Toast, null, 2)}</Text>*/}
<Button
title={'simple toast'}
onPress={() => {
Toast.show('This is a toast.', Toast.SHORT);
}}
/>

<Button
title={'styled toast'}
onPress={() => {
Expand All @@ -94,7 +95,11 @@ export default function App() {
onPress={() => {
Alert.alert('this is an alert');
setTimeout(() => {
Toast.showWithGravity('This is an alert toast.', 5, Toast.TOP);
Toast.showWithGravity(
'This is an alert toast.',
5,
Toast.CENTER,
);
}, 100);
}}
/>
Expand Down
5 changes: 2 additions & 3 deletions ios/RNSimpleToast.mm
Original file line number Diff line number Diff line change
Expand Up @@ -148,16 +148,15 @@ - (CGPoint)rnToast_centerPointForPosition:(NSString *)gravity withToast:(UIView
safeInsets = view.safeAreaInsets;
}

CGFloat topPadding = safeInsets.top;
CGFloat bottomPadding = safeInsets.bottom;

if ([CSToastPositionTop isEqualToString:gravity]) {
CGFloat topPadding = safeInsets.top;
return CGPointMake(view.bounds.size.width / 2.0, (toast.frame.size.height / 2.0) + topPadding);
} else if ([CSToastPositionCenter isEqualToString:gravity]) {
return CGPointMake(view.bounds.size.width / 2.0, view.bounds.size.height / 2.0);
}

// default to bottom
CGFloat bottomPadding = safeInsets.bottom;
return CGPointMake(view.bounds.size.width / 2.0, (view.bounds.size.height - (toast.frame.size.height / 2.0)) - bottomPadding);
}

Expand Down
43 changes: 37 additions & 6 deletions ios/RNToastViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,36 @@ @interface RNToastViewController ()

@implementation RNToastViewController

- (UIWindow *)toastWindow {
// presenting directly from RCTSharedApplication().keyWindow won't work for Alerts
// which is why we have our own VC

- (UIWindow *)toastWindow
{
if (_toastWindow == nil) {
_toastWindow = [[UIWindow alloc] initWithFrame:RCTSharedApplication().keyWindow.bounds];
_toastWindow.rootViewController = [UIViewController new];
_toastWindow.windowLevel = UIWindowLevelAlert + 2;
_toastWindow.userInteractionEnabled = NO;
_toastWindow = [self getUIWindowFromScene];

if (_toastWindow == nil) {
UIWindow *keyWindow = RCTSharedApplication().keyWindow;
if (keyWindow) {
_toastWindow = [[UIWindow alloc] initWithFrame:keyWindow.bounds];
} else {
// keyWindow is nil, so we cannot create and initialize _toastWindow
NSLog(@"Unable to create alert window: keyWindow is nil");
}
}

if (_toastWindow) {
_toastWindow.rootViewController = [UIViewController new];
_toastWindow.windowLevel = UIWindowLevelAlert + 1;
_toastWindow.userInteractionEnabled = NO;
}
}

return _toastWindow;
}

- (void)show:(void (^)(void))completion {
self.modalPresentationStyle = UIModalPresentationFullScreen;
self.modalPresentationStyle = UIModalPresentationOverCurrentContext;
[self.toastWindow setHidden:NO];
[self.toastWindow.rootViewController presentViewController:self animated:NO completion:completion];
}
Expand All @@ -36,4 +54,17 @@ - (void)hide {
_toastWindow = nil;
}

- (UIWindow *)getUIWindowFromScene
{
if (@available(iOS 13.0, *)) {
for (UIScene *scene in RCTSharedApplication().connectedScenes) {
if (scene.activationState == UISceneActivationStateForegroundActive &&
[scene isKindOfClass:[UIWindowScene class]]) {
return [[UIWindow alloc] initWithWindowScene:(UIWindowScene *)scene];
}
}
}
return nil;
}

@end

0 comments on commit 5b8defb

Please sign in to comment.