From 63b51d555bd95b12a327e68c6c79e1892cf2e2ae Mon Sep 17 00:00:00 2001 From: svbutko Date: Wed, 20 Oct 2021 10:26:24 +0300 Subject: [PATCH 01/10] Add UISheetPresentationController Modal options into types --- lib/src/interfaces/Options.ts | 48 +++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/lib/src/interfaces/Options.ts b/lib/src/interfaces/Options.ts index cb8997eab88..c4bca7e2df4 100644 --- a/lib/src/interfaces/Options.ts +++ b/lib/src/interfaces/Options.ts @@ -1086,12 +1086,60 @@ export interface OverlayOptions { handleKeyboardEvents?: boolean; } +export enum ModalDetent { + medium = "medium", + large = "large", +} + export interface ModalOptions { /** * Control whether this modal should be dismiss using swipe gesture when the modalPresentationStyle = 'pageSheet' * #### (iOS specific) */ swipeToDismiss?: boolean; + + /** + * The array of heights where a sheet can rest. + * #### (iOS 15+ specific) + */ + detents?: ModalDetent[], + + /** + * The largest detent that doesn’t dim the view underneath the sheet. + * #### (iOS 15+ specific) + */ + largestUndimmedDetent?: ModalDetent, + + /** + * A boolean value that determines whether scrolling expands the sheet to a larger detent. + * After the sheet reaches its largest detent, scrolling begins. + * #### (iOS 15+ specific) + */ + prefersScrollingExpandsWhenScrolledToEdge?: boolean, + + /** + * A boolean value that determines whether the sheet attaches to the bottom edge of the screen in a compact-height size class. + * #### (iOS 15+ specific) + */ + prefersEdgeAttachedInCompactHeight?: boolean, + + /** + * A boolean value that determines whether the sheet's width matches its view controller's preferred content size. + * #### (iOS 15+ specific) + */ + widthFollowsPreferredContentSizeWhenEdgeAttached?: boolean, + + /** + * The corner radius that the sheet attempts to present with. + * #### (iOS 15+ specific) + */ + preferredCornerRadius?: number; + + /** + * A Boolean value that determines whether the sheet shows a grabber at the top. + * #### (iOS 15+ specific) + */ + prefersGrabberVisible?: boolean; } export interface OptionsPreviewAction { From e576ebf387e8bc1fa0af5761643b1a7a22ed013f Mon Sep 17 00:00:00 2001 From: svbutko Date: Wed, 20 Oct 2021 10:55:27 +0300 Subject: [PATCH 02/10] Add iOS 15 modal options into website's options --- lib/src/interfaces/Options.ts | 2 +- website/docs/api/options-modal.mdx | 59 +++++++++++++++++++++++++++++- 2 files changed, 59 insertions(+), 2 deletions(-) diff --git a/lib/src/interfaces/Options.ts b/lib/src/interfaces/Options.ts index c4bca7e2df4..0c37604ac12 100644 --- a/lib/src/interfaces/Options.ts +++ b/lib/src/interfaces/Options.ts @@ -1136,7 +1136,7 @@ export interface ModalOptions { preferredCornerRadius?: number; /** - * A Boolean value that determines whether the sheet shows a grabber at the top. + * A boolean value that determines whether the sheet shows a grabber at the top. * #### (iOS 15+ specific) */ prefersGrabberVisible?: boolean; diff --git a/website/docs/api/options-modal.mdx b/website/docs/api/options-modal.mdx index 1b26281a50c..4ad4763f6ec 100644 --- a/website/docs/api/options-modal.mdx +++ b/website/docs/api/options-modal.mdx @@ -12,8 +12,65 @@ const options = { ## `swipeToDismiss` -Control wether this modal should be dismiss using swipe gesture when the `modalPresentationStyle` is `pageSheet` +Control whether this modal should be dismissed using swipe gesture when the `modalPresentationStyle` is `pageSheet` | Type | Required | Platform | Default | | ------------------------------------- | -------- | -------- | -------- | | boolean | No | Both | true | + +## `detents` + +The array of heights where a sheet can rest. + +| Type | Required | Platform | Default | +| ------------------------------------- | -------- | -------- | -------- | +| ModalDetent[] | No | iOS 15+ | 'large' | + +## `largestUndimmedDetent` + +The largest detent that doesn’t dim the view underneath the sheet. + +| Type | Required | Platform | Default | +| ------------------------------------- | -------- | -------- | --------- | +| ModalDetent | No | iOS 15+ | undefined | + +## `prefersScrollingExpandsWhenScrolledToEdge` + +A boolean value that determines whether scrolling expands the sheet to a larger detent. +After the sheet reaches its largest detent, scrolling begins. + +| Type | Required | Platform | Default | +| ------------------------------------- | -------- | -------- | --------- | +| boolean | No | iOS 15+ | true | + +## `prefersEdgeAttachedInCompactHeight` + +A boolean value that determines whether the sheet attaches to the bottom edge of the screen in a compact-height size class. + +| Type | Required | Platform | Default | +| ------------------------------------- | -------- | -------- | --------- | +| boolean | No | iOS 15+ | false | + +## `widthFollowsPreferredContentSizeWhenEdgeAttached` + +A boolean value that determines whether the sheet's width matches its view controller's preferred content size. + +| Type | Required | Platform | Default | +| ------------------------------------- | -------- | -------- | --------- | +| boolean | No | iOS 15+ | false | + +## `preferredCornerRadius` + +The corner radius that the sheet attempts to present with. + +| Type | Required | Platform | Default | +| ------------------------------------- | -------- | -------- | --------- | +| number | No | iOS 15+ | undefined | + +## `prefersGrabberVisible` + +A boolean value that determines whether the sheet shows a grabber at the top. + +| Type | Required | Platform | Default | +| ------------------------------------- | -------- | -------- | --------- | +| boolean | No | iOS 15+ | false | From cf73780dfd58e3946db96e1d51509dc316fb1417 Mon Sep 17 00:00:00 2001 From: svbutko Date: Wed, 20 Oct 2021 11:17:59 +0300 Subject: [PATCH 03/10] Add RNNModalOptions --- lib/ios/RNNModalOptions.h | 7 +++++++ lib/ios/RNNModalOptions.m | 25 +++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/lib/ios/RNNModalOptions.h b/lib/ios/RNNModalOptions.h index 940c3305b43..18cf5f1ddce 100644 --- a/lib/ios/RNNModalOptions.h +++ b/lib/ios/RNNModalOptions.h @@ -3,5 +3,12 @@ @interface RNNModalOptions : RNNOptions @property(nonatomic, strong) Bool *swipeToDismiss; +@property(nonatomic, strong) Bool *prefersScrollingExpandsWhenScrolledToEdge; +@property(nonatomic, strong) Bool *prefersEdgeAttachedInCompactHeight; +@property(nonatomic, strong) Bool *widthFollowsPreferredContentSizeWhenEdgeAttached; +@property(nonatomic, strong) Bool *prefersGrabberVisible; +@property(nonatomic, strong) Number *preferredCornerRadius; +@property(nonatomic, strong) NSArray *detents; +@property(nonatomic, strong) Text *largestUndimmedDetent; @end diff --git a/lib/ios/RNNModalOptions.m b/lib/ios/RNNModalOptions.m index cc795cc82c5..70aa08fcfe6 100644 --- a/lib/ios/RNNModalOptions.m +++ b/lib/ios/RNNModalOptions.m @@ -1,16 +1,41 @@ #import "RNNModalOptions.h" +#import "OptionsArrayParser.h" @implementation RNNModalOptions - (instancetype)initWithDict:(NSDictionary *)dict { self = [super initWithDict:dict]; self.swipeToDismiss = [BoolParser parse:dict key:@"swipeToDismiss"]; + self.prefersScrollingExpandsWhenScrolledToEdge = [BoolParser parse:dict key:@"prefersScrollingExpandsWhenScrolledToEdge"]; + self.prefersEdgeAttachedInCompactHeight = [BoolParser parse:dict key:@"prefersEdgeAttachedInCompactHeight"]; + self.widthFollowsPreferredContentSizeWhenEdgeAttached = [BoolParser parse:dict key:@"widthFollowsPreferredContentSizeWhenEdgeAttached"]; + self.prefersGrabberVisible = [BoolParser parse:dict key:@"prefersGrabberVisible"]; + self.preferredCornerRadius = [NumberParser parse:dict key:@"preferredCornerRadius"]; + self.largestUndimmedDetent = [TextParser parse:dict key:@"largestUndimmedDetent"]; + self.detents = [OptionsArrayParser parse:dict key:@"detents" ofClass:Text.class]; return self; } - (void)mergeOptions:(RNNModalOptions *)options { if (options.swipeToDismiss.hasValue) self.swipeToDismiss = options.swipeToDismiss; + if (options.prefersScrollingExpandsWhenScrolledToEdge.hasValue) { + self.prefersScrollingExpandsWhenScrolledToEdge = options.prefersScrollingExpandsWhenScrolledToEdge; + } + if (options.prefersEdgeAttachedInCompactHeight.hasValue) + self.prefersEdgeAttachedInCompactHeight = options.prefersEdgeAttachedInCompactHeight; + if (options.widthFollowsPreferredContentSizeWhenEdgeAttached.hasValue) { + self.widthFollowsPreferredContentSizeWhenEdgeAttached = options.widthFollowsPreferredContentSizeWhenEdgeAttached; + } + if (options.prefersGrabberVisible.hasValue) + self.prefersGrabberVisible = options.prefersGrabberVisible; + if (options.preferredCornerRadius.hasValue) + self.preferredCornerRadius = options.preferredCornerRadius; + if (options.largestUndimmedDetent.hasValue) + self.largestUndimmedDetent = options.largestUndimmedDetent; + if (options.detents) + self.detents = options.detents; + } @end From 13a847a221dc7d4361ff4a8a0e303300d8299eff Mon Sep 17 00:00:00 2001 From: svbutko Date: Wed, 20 Oct 2021 12:29:22 +0300 Subject: [PATCH 04/10] Add the sheet options into RNNCommandsHandler and add enum converter --- lib/ios/RNNCommandsHandler.m | 19 +++++++++++++++++++ lib/ios/RNNConvert.h | 2 ++ lib/ios/RNNConvert.m | 6 ++++++ 3 files changed, 27 insertions(+) diff --git a/lib/ios/RNNCommandsHandler.m b/lib/ios/RNNCommandsHandler.m index 5eb5078892d..63090a9c66e 100644 --- a/lib/ios/RNNCommandsHandler.m +++ b/lib/ios/RNNCommandsHandler.m @@ -367,6 +367,25 @@ - (void)showModal:(NSDictionary *)layout RNNNavigationOptions *withDefault = newVc.resolveOptionsWithDefault; [_layoutManager addPendingViewController:newVc]; + + if (@available(iOS 15.0, *)) { + UISheetPresentationController *sheet = [newVc sheetPresentationController]; + + if (sheet) { + [sheet setPrefersScrollingExpandsWhenScrolledToEdge:[withDefault.modal.prefersScrollingExpandsWhenScrolledToEdge withDefault:true]]; + [sheet setPrefersEdgeAttachedInCompactHeight:[withDefault.modal.prefersEdgeAttachedInCompactHeight withDefault:false]]; + [sheet setWidthFollowsPreferredContentSizeWhenEdgeAttached:[withDefault.modal.widthFollowsPreferredContentSizeWhenEdgeAttached withDefault:false]]; + [sheet setPrefersGrabberVisible:[withDefault.modal.prefersGrabberVisible withDefault:false]]; + [sheet setLargestUndimmedDetentIdentifier:[RNNConvert UISheetPresentationControllerDetentIdentifier:[withDefault.modal.largestUndimmedDetent withDefault:nil]]]; + if (withDefault.modal.detents) { + // FIXME: This should be handled with conversion rather than straightforward usage + [sheet setDetents:withDefault.modal.detents]; + } + if (withDefault.modal.preferredCornerRadius.hasValue) { + [sheet setPreferredCornerRadius:[withDefault.modal.preferredCornerRadius.get doubleValue]]; + } + } + } __weak UIViewController *weakNewVC = newVc; newVc.waitForRender = [withDefault.animations.showModal.enter shouldWaitForRender]; diff --git a/lib/ios/RNNConvert.h b/lib/ios/RNNConvert.h index b21c73b042d..3fbf16ff567 100644 --- a/lib/ios/RNNConvert.h +++ b/lib/ios/RNNConvert.h @@ -7,4 +7,6 @@ + (UIModalTransitionStyle)UIModalTransitionStyle:(id)json; ++ (UISheetPresentationControllerDetentIdentifier)UISheetPresentationControllerDetentIdentifier:(id)json; + @end diff --git a/lib/ios/RNNConvert.m b/lib/ios/RNNConvert.m index 873042dec5e..31e23a4a4d5 100644 --- a/lib/ios/RNNConvert.m +++ b/lib/ios/RNNConvert.m @@ -32,4 +32,10 @@ + (UIModalPresentationStyle)defaultModalPresentationStyle { }), UIModalPresentationFullScreen, integerValue) +RCT_ENUM_CONVERTER(UISheetPresentationControllerDetentIdentifier, (@{ + @"medium" : @(UISheetPresentationControllerDetentIdentifierMedium), + @"large" : @(UISheetPresentationControllerDetentIdentifierLarge) + }), + nil, integerValue) + @end From edf4aa5a593830eb15818d1bbdb0370d9369f6d5 Mon Sep 17 00:00:00 2001 From: svbutko Date: Wed, 20 Oct 2021 12:56:23 +0300 Subject: [PATCH 05/10] Add FIXME to converters --- lib/ios/RNNCommandsHandler.m | 6 ++++-- lib/ios/RNNConvert.m | 11 ++++++----- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/lib/ios/RNNCommandsHandler.m b/lib/ios/RNNCommandsHandler.m index 63090a9c66e..ea89c63d526 100644 --- a/lib/ios/RNNCommandsHandler.m +++ b/lib/ios/RNNCommandsHandler.m @@ -376,10 +376,12 @@ - (void)showModal:(NSDictionary *)layout [sheet setPrefersEdgeAttachedInCompactHeight:[withDefault.modal.prefersEdgeAttachedInCompactHeight withDefault:false]]; [sheet setWidthFollowsPreferredContentSizeWhenEdgeAttached:[withDefault.modal.widthFollowsPreferredContentSizeWhenEdgeAttached withDefault:false]]; [sheet setPrefersGrabberVisible:[withDefault.modal.prefersGrabberVisible withDefault:false]]; - [sheet setLargestUndimmedDetentIdentifier:[RNNConvert UISheetPresentationControllerDetentIdentifier:[withDefault.modal.largestUndimmedDetent withDefault:nil]]]; + // FIXME: This should be handled with conversion which is incorrect + //[sheet setLargestUndimmedDetentIdentifier:[RNNConvert UISheetPresentationControllerDetentIdentifier:[withDefault.modal.largestUndimmedDetent withDefault:nil]]]; if (withDefault.modal.detents) { // FIXME: This should be handled with conversion rather than straightforward usage - [sheet setDetents:withDefault.modal.detents]; + //[sheet setDetents:withDefault.modal.detents]; + [sheet setDetents:[[NSArray alloc] initWithObjects:UISheetPresentationControllerDetentIdentifierMedium, UISheetPresentationControllerDetentIdentifierLarge, nil]]; } if (withDefault.modal.preferredCornerRadius.hasValue) { [sheet setPreferredCornerRadius:[withDefault.modal.preferredCornerRadius.get doubleValue]]; diff --git a/lib/ios/RNNConvert.m b/lib/ios/RNNConvert.m index 31e23a4a4d5..15b32768d9b 100644 --- a/lib/ios/RNNConvert.m +++ b/lib/ios/RNNConvert.m @@ -32,10 +32,11 @@ + (UIModalPresentationStyle)defaultModalPresentationStyle { }), UIModalPresentationFullScreen, integerValue) -RCT_ENUM_CONVERTER(UISheetPresentationControllerDetentIdentifier, (@{ - @"medium" : @(UISheetPresentationControllerDetentIdentifierMedium), - @"large" : @(UISheetPresentationControllerDetentIdentifierLarge) - }), - nil, integerValue) +//FIXME: The conversion is incorrect +//RCT_ENUM_CONVERTER(UISheetPresentationControllerDetentIdentifier, (@{ +// @"medium" : UISheetPresentationControllerDetentIdentifierMedium, +// @"large" : UISheetPresentationControllerDetentIdentifierLarge +// }), +// nil, integerValue) @end From 7bf4c8db6628c0fc22e54f0747279f60b3e94b61 Mon Sep 17 00:00:00 2001 From: svbutko Date: Wed, 20 Oct 2021 13:45:36 +0300 Subject: [PATCH 06/10] Add FIXME to converters --- lib/ios/RNNCommandsHandler.m | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/lib/ios/RNNCommandsHandler.m b/lib/ios/RNNCommandsHandler.m index ea89c63d526..e763db8df17 100644 --- a/lib/ios/RNNCommandsHandler.m +++ b/lib/ios/RNNCommandsHandler.m @@ -367,29 +367,33 @@ - (void)showModal:(NSDictionary *)layout RNNNavigationOptions *withDefault = newVc.resolveOptionsWithDefault; [_layoutManager addPendingViewController:newVc]; + + __weak UIViewController *weakNewVC = newVc; if (@available(iOS 15.0, *)) { - UISheetPresentationController *sheet = [newVc sheetPresentationController]; + UISheetPresentationController *sheet = [weakNewVC sheetPresentationController]; if (sheet) { [sheet setPrefersScrollingExpandsWhenScrolledToEdge:[withDefault.modal.prefersScrollingExpandsWhenScrolledToEdge withDefault:true]]; [sheet setPrefersEdgeAttachedInCompactHeight:[withDefault.modal.prefersEdgeAttachedInCompactHeight withDefault:false]]; [sheet setWidthFollowsPreferredContentSizeWhenEdgeAttached:[withDefault.modal.widthFollowsPreferredContentSizeWhenEdgeAttached withDefault:false]]; [sheet setPrefersGrabberVisible:[withDefault.modal.prefersGrabberVisible withDefault:false]]; - // FIXME: This should be handled with conversion which is incorrect - //[sheet setLargestUndimmedDetentIdentifier:[RNNConvert UISheetPresentationControllerDetentIdentifier:[withDefault.modal.largestUndimmedDetent withDefault:nil]]]; + // FIXME: This should be handled with conversion which is incorrect + if (withDefault.modal.largestUndimmedDetent.hasValue) { + //[sheet setLargestUndimmedDetentIdentifier:[RNNConvert UISheetPresentationControllerDetentIdentifier:[withDefault.modal.largestUndimmedDetent withDefault:nil]]]; + [sheet setLargestUndimmedDetentIdentifier:UISheetPresentationControllerDetentIdentifierLarge]; + } if (withDefault.modal.detents) { // FIXME: This should be handled with conversion rather than straightforward usage //[sheet setDetents:withDefault.modal.detents]; - [sheet setDetents:[[NSArray alloc] initWithObjects:UISheetPresentationControllerDetentIdentifierMedium, UISheetPresentationControllerDetentIdentifierLarge, nil]]; + //[sheet setDetents: @[UISheetPresentationControllerDetentIdentifierMedium, UISheetPresentationControllerDetentIdentifierLarge]]; } if (withDefault.modal.preferredCornerRadius.hasValue) { [sheet setPreferredCornerRadius:[withDefault.modal.preferredCornerRadius.get doubleValue]]; } } } - - __weak UIViewController *weakNewVC = newVc; + newVc.waitForRender = [withDefault.animations.showModal.enter shouldWaitForRender]; newVc.modalPresentationStyle = [RNNConvert UIModalPresentationStyle:[withDefault.modalPresentationStyle withDefault:@"default"]]; From 2320cfff4775afd12e2c94d1a3c4025b476c6e2d Mon Sep 17 00:00:00 2001 From: svbutko Date: Wed, 20 Oct 2021 13:46:08 +0300 Subject: [PATCH 07/10] Add FIXME to converters --- playground/src/screens/NavigationScreen.tsx | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/playground/src/screens/NavigationScreen.tsx b/playground/src/screens/NavigationScreen.tsx index eaa893930a6..c8e861fe4a9 100644 --- a/playground/src/screens/NavigationScreen.tsx +++ b/playground/src/screens/NavigationScreen.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { Platform } from 'react-native'; -import { NavigationComponentProps, OptionsModalPresentationStyle } from 'react-native-navigation'; +import { ModalDetent, NavigationComponentProps, OptionsModalPresentationStyle } from 'react-native-navigation'; import Root from '../components/Root'; import Button from '../components/Button'; import Navigation from './../services/Navigation'; @@ -43,6 +43,7 @@ export default class NavigationScreen extends React.Component {