diff --git a/ios/gamma/modals/form-sheet/RNSFormSheetAppearanceApplicator.h b/ios/gamma/modals/form-sheet/RNSFormSheetAppearanceApplicator.h deleted file mode 100644 index d1ae624dfb..0000000000 --- a/ios/gamma/modals/form-sheet/RNSFormSheetAppearanceApplicator.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -#import -#import "RNSFormSheetProviders.h" - -@class RNSFormSheetAppearanceCoordinator; -@class RNSFormSheetContentController; - -NS_ASSUME_NONNULL_BEGIN - -@interface RNSFormSheetAppearanceApplicator : NSObject - -- (void)updateAppearanceIfNeededWithAppearanceProvider:(id)appearanceProvider - behaviorProvider:(id)behaviorProvider - controller:(RNSFormSheetContentController *)controller - coordinator:(RNSFormSheetAppearanceCoordinator *)coordinator; - -- (void)resetInitialDetent; - -@end - -NS_ASSUME_NONNULL_END diff --git a/ios/gamma/modals/form-sheet/RNSFormSheetAppearanceCoordinator.h b/ios/gamma/modals/form-sheet/RNSFormSheetAppearanceCoordinator.h deleted file mode 100644 index df2ab406cc..0000000000 --- a/ios/gamma/modals/form-sheet/RNSFormSheetAppearanceCoordinator.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#import - -#import "RNSFormSheetAppearanceUpdateFlags.h" - -NS_ASSUME_NONNULL_BEGIN - -@interface RNSFormSheetAppearanceCoordinator : NSObject - -- (void)setNeeds:(RNSFormSheetAppearanceUpdateFlags)flags; - -- (BOOL)needsAll:(RNSFormSheetAppearanceUpdateFlags)flags; - -- (void)updateIfNeeds:(RNSFormSheetAppearanceUpdateFlags)flags performOperations:(dispatch_block_t)block; - -@end - -NS_ASSUME_NONNULL_END diff --git a/ios/gamma/modals/form-sheet/RNSFormSheetAppearanceCoordinator.mm b/ios/gamma/modals/form-sheet/RNSFormSheetAppearanceCoordinator.mm deleted file mode 100644 index cf10bc84e9..0000000000 --- a/ios/gamma/modals/form-sheet/RNSFormSheetAppearanceCoordinator.mm +++ /dev/null @@ -1,37 +0,0 @@ -#import "RNSFormSheetAppearanceCoordinator.h" - -@implementation RNSFormSheetAppearanceCoordinator { - RNSFormSheetAppearanceUpdateFlags _updateFlags; -} - -- (instancetype)init -{ - if (self = [super init]) { - _updateFlags = RNSFormSheetAppearanceUpdateFlagsNone; - } - return self; -} - -- (void)setNeeds:(RNSFormSheetAppearanceUpdateFlags)flags -{ - _updateFlags |= flags; -} - -- (BOOL)needsAll:(RNSFormSheetAppearanceUpdateFlags)flags -{ - if (flags == RNSFormSheetAppearanceUpdateFlagsNone) { - return NO; - } - - return (_updateFlags & flags) == flags; -} - -- (void)updateIfNeeds:(RNSFormSheetAppearanceUpdateFlags)flags performOperations:(dispatch_block_t)block -{ - if ([self needsAll:flags]) { - block(); - _updateFlags &= ~flags; - } -} - -@end diff --git a/ios/gamma/modals/form-sheet/RNSFormSheetAppearanceUpdateFlags.h b/ios/gamma/modals/form-sheet/RNSFormSheetAppearanceUpdateFlags.h deleted file mode 100644 index fd827a73ac..0000000000 --- a/ios/gamma/modals/form-sheet/RNSFormSheetAppearanceUpdateFlags.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#import - -typedef NS_OPTIONS(NSUInteger, RNSFormSheetAppearanceUpdateFlags) { - RNSFormSheetAppearanceUpdateFlagsNone = 0, - // The sheet needs to be presented or dismissed to match the requested open state. - RNSFormSheetAppearanceUpdateFlagsPresentation = 1 << 0, - // The sheet's visual appearance configuration (detents, grabber, dimming view) needs to be re-applied. - RNSFormSheetAppearanceUpdateFlagsConfiguration = 1 << 1, -}; diff --git a/ios/gamma/modals/form-sheet/RNSFormSheetConfigurationApplicator.h b/ios/gamma/modals/form-sheet/RNSFormSheetConfigurationApplicator.h new file mode 100644 index 0000000000..8daf33484d --- /dev/null +++ b/ios/gamma/modals/form-sheet/RNSFormSheetConfigurationApplicator.h @@ -0,0 +1,22 @@ +#pragma once + +#import +#import "RNSFormSheetProviders.h" + +@class RNSFormSheetUpdateCoordinator; +@class RNSFormSheetContentController; + +NS_ASSUME_NONNULL_BEGIN + +@interface RNSFormSheetConfigurationApplicator : NSObject + +- (void)applyConfigurationIfNeededWithAppearanceProvider:(id)appearanceProvider + behaviorProvider:(id)behaviorProvider + controller:(RNSFormSheetContentController *)controller + coordinator:(RNSFormSheetUpdateCoordinator *)coordinator; + +- (void)resetInitialDetent; + +@end + +NS_ASSUME_NONNULL_END diff --git a/ios/gamma/modals/form-sheet/RNSFormSheetAppearanceApplicator.mm b/ios/gamma/modals/form-sheet/RNSFormSheetConfigurationApplicator.mm similarity index 57% rename from ios/gamma/modals/form-sheet/RNSFormSheetAppearanceApplicator.mm rename to ios/gamma/modals/form-sheet/RNSFormSheetConfigurationApplicator.mm index 1d948d2765..68059d4cb9 100644 --- a/ios/gamma/modals/form-sheet/RNSFormSheetAppearanceApplicator.mm +++ b/ios/gamma/modals/form-sheet/RNSFormSheetConfigurationApplicator.mm @@ -1,13 +1,13 @@ -#import "RNSFormSheetAppearanceApplicator.h" +#import "RNSFormSheetConfigurationApplicator.h" #import -#import "RNSFormSheetAppearanceCoordinator.h" -#import "RNSFormSheetAppearanceUpdateFlags.h" #import "RNSFormSheetContentController.h" #import "RNSFormSheetDetentResolver.h" +#import "RNSFormSheetUpdateCoordinator.h" +#import "RNSFormSheetUpdateFlags.h" -@implementation RNSFormSheetAppearanceApplicator { +@implementation RNSFormSheetConfigurationApplicator { BOOL _initialDetentApplied; } @@ -24,24 +24,26 @@ - (void)resetInitialDetent _initialDetentApplied = NO; } -- (void)updateAppearanceIfNeededWithAppearanceProvider:(id)appearanceProvider - behaviorProvider:(id)behaviorProvider - controller:(RNSFormSheetContentController *)controller - coordinator:(RNSFormSheetAppearanceCoordinator *)coordinator +- (void)applyConfigurationIfNeededWithAppearanceProvider:(id)appearanceProvider + behaviorProvider:(id)behaviorProvider + controller:(RNSFormSheetContentController *)controller + coordinator:(RNSFormSheetUpdateCoordinator *)coordinator { - [coordinator updateIfNeeds:RNSFormSheetAppearanceUpdateFlagsConfiguration - performOperations:^{ - [self updateSheetConfigurationForAppearanceProvider:appearanceProvider - behaviorProvider:behaviorProvider - controller:controller]; - }]; + RNSFormSheetUpdateFlags configFlags = RNSFormSheetUpdateFlagsAppearance | RNSFormSheetUpdateFlagsBehavior; + + [coordinator updateIfAnyNeeded:configFlags + performOperations:^{ + [self applyConfigurationWithAppearanceProvider:appearanceProvider + behaviorProvider:behaviorProvider + controller:controller]; + }]; } #pragma mark - Updaters -- (void)updateSheetConfigurationForAppearanceProvider:(id)appearanceProvider - behaviorProvider:(id)behaviorProvider - controller:(RNSFormSheetContentController *)controller +- (void)applyConfigurationWithAppearanceProvider:(id)appearanceProvider + behaviorProvider:(id)behaviorProvider + controller:(RNSFormSheetContentController *)controller { #if !TARGET_OS_TV UISheetPresentationController *sheet = controller.sheetPresentationController; @@ -49,6 +51,8 @@ - (void)updateSheetConfigurationForAppearanceProvider:(id *nativeDetents = [RNSFormSheetDetentResolver buildSheetDetentsForFractions:behaviorProvider.detents]; @@ -60,26 +64,30 @@ - (void)updateSheetConfigurationForAppearanceProvider:(id @@ -17,8 +17,8 @@ @interface RNSFormSheetContentController () presentationProvider = self.presentationProvider; @@ -122,16 +130,15 @@ - (void)dismissIfNeeded [self dismissViewControllerAnimated:YES completion:nil]; } -#pragma mark - Appearance +#pragma mark - Sheet Configuration -- (void)updateAppearanceIfNeeded +- (void)updateConfigurationIfNeeded { id appearanceProvider = self.appearanceProvider; id behaviorProvider = self.behaviorProvider; RCTAssert(appearanceProvider != nil, @"[RNScreens] Appearance provider must be set before updating appearance."); - - RCTAssert(behaviorProvider != nil, @"[RNScreens] Behavior provider must be set before updating appearance."); + RCTAssert(behaviorProvider != nil, @"[RNScreens] Behavior provider must be set before updating behavior."); if (appearanceProvider == nil || behaviorProvider == nil) { return; @@ -139,31 +146,30 @@ - (void)updateAppearanceIfNeeded if (_needsInitialDetentReset) { _needsInitialDetentReset = NO; - [_appearanceApplicator resetInitialDetent]; + [_configurationApplicator resetInitialDetent]; } - [_appearanceApplicator updateAppearanceIfNeededWithAppearanceProvider:appearanceProvider - behaviorProvider:behaviorProvider - controller:self - coordinator:_appearanceCoordinator]; - - // TODO: @t0maboro - decouple presentation logic from AppearanceCoordinator - [_appearanceCoordinator updateIfNeeds:RNSFormSheetAppearanceUpdateFlagsPresentation - performOperations:^{ - [self updatePresentationState]; - }]; + [_configurationApplicator applyConfigurationIfNeededWithAppearanceProvider:appearanceProvider + behaviorProvider:behaviorProvider + controller:self + coordinator:_updateCoordinator]; } #pragma mark - Signals - (void)setNeedsPresentationUpdate { - [_appearanceCoordinator setNeeds:RNSFormSheetAppearanceUpdateFlagsPresentation]; + [_updateCoordinator setNeeds:RNSFormSheetUpdateFlagsPresentation]; } - (void)setNeedsAppearanceUpdate { - [_appearanceCoordinator setNeeds:RNSFormSheetAppearanceUpdateFlagsConfiguration]; + [_updateCoordinator setNeeds:RNSFormSheetUpdateFlagsAppearance]; +} + +- (void)setNeedsBehaviorUpdate +{ + [_updateCoordinator setNeeds:RNSFormSheetUpdateFlagsBehavior]; } - (void)setNeedsInitialDetentReset @@ -175,7 +181,8 @@ - (void)setNeedsInitialDetentReset - (void)flushPendingUpdates { - [self updateAppearanceIfNeeded]; + [self updateConfigurationIfNeeded]; + [self updatePresentationIfNeeded]; } #pragma mark - UIAdaptivePresentationControllerDelegate diff --git a/ios/gamma/modals/form-sheet/RNSFormSheetHostComponentView.mm b/ios/gamma/modals/form-sheet/RNSFormSheetHostComponentView.mm index a9763f4e0c..affa11e822 100644 --- a/ios/gamma/modals/form-sheet/RNSFormSheetHostComponentView.mm +++ b/ios/gamma/modals/form-sheet/RNSFormSheetHostComponentView.mm @@ -177,6 +177,7 @@ - (void)updateProps:(const facebook::react::Props::Shared &)props // ALWAYS refresh the sheet configuration when reopening, // because UIKit destroys the presentationController after the modal is dismissed. [_controller setNeedsAppearanceUpdate]; + [_controller setNeedsBehaviorUpdate]; // Reset the initial-detent applied flag when reopening so the // configured initialDetentIndex can be applied again. [_controller setNeedsInitialDetentReset]; @@ -185,7 +186,14 @@ - (void)updateProps:(const facebook::react::Props::Shared &)props if (oldComponentProps.detents != newComponentProps.detents) { _detents = newComponentProps.detents; - [_controller setNeedsAppearanceUpdate]; + [_controller setNeedsBehaviorUpdate]; + } + + if (oldComponentProps.prefersScrollingExpandsWhenScrolledToEdge != + newComponentProps.prefersScrollingExpandsWhenScrolledToEdge) { + _prefersScrollingExpandsWhenScrolledToEdge = + static_cast(newComponentProps.prefersScrollingExpandsWhenScrolledToEdge); + [_controller setNeedsBehaviorUpdate]; } if (oldComponentProps.prefersGrabberVisible != newComponentProps.prefersGrabberVisible) { @@ -207,13 +215,6 @@ - (void)updateProps:(const facebook::react::Props::Shared &)props _initialDetentIndex = newComponentProps.initialDetentIndex; } - if (oldComponentProps.prefersScrollingExpandsWhenScrolledToEdge != - newComponentProps.prefersScrollingExpandsWhenScrolledToEdge) { - _prefersScrollingExpandsWhenScrolledToEdge = - static_cast(newComponentProps.prefersScrollingExpandsWhenScrolledToEdge); - [_controller setNeedsAppearanceUpdate]; - } - [super updateProps:props oldProps:oldProps]; } diff --git a/ios/gamma/modals/form-sheet/RNSFormSheetUpdateCoordinator.h b/ios/gamma/modals/form-sheet/RNSFormSheetUpdateCoordinator.h new file mode 100644 index 0000000000..902df71e4b --- /dev/null +++ b/ios/gamma/modals/form-sheet/RNSFormSheetUpdateCoordinator.h @@ -0,0 +1,21 @@ +#pragma once + +#import + +#import "RNSFormSheetUpdateFlags.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface RNSFormSheetUpdateCoordinator : NSObject + +- (void)setNeeds:(RNSFormSheetUpdateFlags)flags; + +- (BOOL)needsAll:(RNSFormSheetUpdateFlags)flags; +- (BOOL)needsAny:(RNSFormSheetUpdateFlags)flags; + +- (void)updateIfNeeded:(RNSFormSheetUpdateFlags)flags performOperations:(dispatch_block_t)block; +- (void)updateIfAnyNeeded:(RNSFormSheetUpdateFlags)flags performOperations:(dispatch_block_t)block; + +@end + +NS_ASSUME_NONNULL_END diff --git a/ios/gamma/modals/form-sheet/RNSFormSheetUpdateCoordinator.mm b/ios/gamma/modals/form-sheet/RNSFormSheetUpdateCoordinator.mm new file mode 100644 index 0000000000..b2a484a168 --- /dev/null +++ b/ios/gamma/modals/form-sheet/RNSFormSheetUpdateCoordinator.mm @@ -0,0 +1,52 @@ +#import "RNSFormSheetUpdateCoordinator.h" + +@implementation RNSFormSheetUpdateCoordinator { + RNSFormSheetUpdateFlags _updateFlags; +} + +- (instancetype)init +{ + if (self = [super init]) { + _updateFlags = RNSFormSheetUpdateFlagsNone; + } + return self; +} + +- (void)setNeeds:(RNSFormSheetUpdateFlags)flags +{ + _updateFlags |= flags; +} + +- (BOOL)needsAll:(RNSFormSheetUpdateFlags)flags +{ + if (flags == RNSFormSheetUpdateFlagsNone) { + return NO; + } + return (_updateFlags & flags) == flags; +} + +- (BOOL)needsAny:(RNSFormSheetUpdateFlags)flags +{ + if (flags == RNSFormSheetUpdateFlagsNone) { + return NO; + } + return (_updateFlags & flags) != 0; +} + +- (void)updateIfNeeded:(RNSFormSheetUpdateFlags)flags performOperations:(dispatch_block_t)block +{ + if ([self needsAll:flags]) { + block(); + _updateFlags &= ~flags; + } +} + +- (void)updateIfAnyNeeded:(RNSFormSheetUpdateFlags)flags performOperations:(dispatch_block_t)block +{ + if ([self needsAny:flags]) { + block(); + _updateFlags &= ~flags; + } +} + +@end diff --git a/ios/gamma/modals/form-sheet/RNSFormSheetUpdateFlags.h b/ios/gamma/modals/form-sheet/RNSFormSheetUpdateFlags.h new file mode 100644 index 0000000000..b8f67d4434 --- /dev/null +++ b/ios/gamma/modals/form-sheet/RNSFormSheetUpdateFlags.h @@ -0,0 +1,13 @@ +#pragma once + +#import + +typedef NS_OPTIONS(NSUInteger, RNSFormSheetUpdateFlags) { + RNSFormSheetUpdateFlagsNone = 0, + // The sheet needs to be presented or dismissed to match the requested open state. + RNSFormSheetUpdateFlagsPresentation = 1 << 0, + // The sheet's visual appearance configuration (grabber, dimming view, corner radius) needs to be re-applied. + RNSFormSheetUpdateFlagsAppearance = 1 << 1, + // The sheet's behavioral layout (detents, scrolling config) needs to be re-applied. + RNSFormSheetUpdateFlagsBehavior = 1 << 2, +};