@lodev09/react-native-true-sheet 4.0.0-beta.2 → 4.0.0-beta.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -4
- package/android/build.gradle +22 -1
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetContainerView.kt +50 -16
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetContentView.kt +302 -184
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetContentViewManager.kt +5 -1
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetFooterView.kt +21 -110
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetOverlayView.kt +116 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetOverlayViewManager.kt +45 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetPackage.kt +2 -1
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetStateUpdater.kt +18 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetView.kt +119 -50
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewController.kt +360 -163
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewManager.kt +54 -12
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetBottomSheetView.kt +22 -9
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetCoordinatorLayout.kt +84 -5
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetDetentCalculator.kt +104 -39
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetDimView.kt +3 -0
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetOverlayRootView.kt +137 -0
- package/android/src/main/java/com/lodev09/truesheet/events/TrueSheetLifecycleEvents.kt +15 -0
- package/android/src/main/java/com/lodev09/truesheet/utils/KeyboardUtils.kt +15 -2
- package/android/src/main/java/com/lodev09/truesheet/utils/ScreenUtils.kt +0 -12
- package/android/src/main/java/com/lodev09/truesheet/utils/ViewUtils.kt +19 -7
- package/android/src/main/jni/TrueSheetSpec.h +1 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewComponentDescriptor.h +1 -9
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewShadowNode.cpp +110 -30
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewShadowNode.h +30 -7
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewState.cpp +2 -2
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewState.h +9 -8
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewComponentDescriptor.h +3 -5
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewShadowNode.cpp +9 -3
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewShadowNode.h +3 -6
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewState.cpp +1 -1
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewState.h +4 -6
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetInsets.cpp +1 -1
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetInsets.h +1 -1
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetLayoutUtils.h +43 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetOverlayViewComponentDescriptor.h +21 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetOverlayViewShadowNode.cpp +17 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetOverlayViewShadowNode.h +33 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewComponentDescriptor.h +3 -5
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewShadowNode.cpp +7 -40
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewShadowNode.h +3 -7
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewState.cpp +3 -5
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewState.h +4 -5
- package/ios/TrueSheetContainerView.h +27 -7
- package/ios/TrueSheetContainerView.mm +31 -11
- package/ios/TrueSheetContentView.h +43 -15
- package/ios/TrueSheetContentView.mm +211 -189
- package/ios/TrueSheetFooterView.h +6 -0
- package/ios/TrueSheetFooterView.mm +93 -17
- package/ios/TrueSheetModule.h +2 -7
- package/ios/TrueSheetModule.mm +7 -16
- package/ios/TrueSheetOverlayView.h +32 -0
- package/ios/TrueSheetOverlayView.mm +161 -0
- package/ios/TrueSheetView.mm +212 -55
- package/ios/TrueSheetViewController.h +31 -3
- package/ios/TrueSheetViewController.mm +393 -94
- package/ios/core/TrueSheetBlurView.h +0 -2
- package/ios/core/TrueSheetBlurView.mm +3 -36
- package/ios/core/TrueSheetDetentCalculator.h +7 -1
- package/ios/core/TrueSheetDetentCalculator.mm +27 -4
- package/ios/core/TrueSheetGrabberView.mm +13 -3
- package/ios/core/TrueSheetKeyboardObserver.mm +2 -0
- package/ios/core/TrueSheetOverlayContainerView.h +31 -0
- package/ios/core/TrueSheetOverlayContainerView.mm +35 -0
- package/ios/events/TrueSheetLifecycleEvents.h +2 -0
- package/ios/events/TrueSheetLifecycleEvents.mm +8 -0
- package/ios/tvos/TrueSheetStubs.mm +12 -0
- package/ios/utils/UIView+ScrollEdgeInteraction.h +1 -0
- package/ios/utils/UIView+ScrollEdgeInteraction.mm +24 -2
- package/lib/module/TrueSheet.js +173 -39
- package/lib/module/TrueSheet.js.map +1 -1
- package/lib/module/TrueSheet.web.js +218 -243
- package/lib/module/TrueSheet.web.js.map +1 -1
- package/lib/module/TrueSheetBackground.js +15 -0
- package/lib/module/TrueSheetBackground.js.map +1 -0
- package/lib/module/TrueSheetOverlay.js +30 -0
- package/lib/module/TrueSheetOverlay.js.map +1 -0
- package/lib/module/TrueSheetOverlay.web.js +35 -0
- package/lib/module/TrueSheetOverlay.web.js.map +1 -0
- package/lib/module/TrueSheetPeek.web.js +20 -15
- package/lib/module/TrueSheetPeek.web.js.map +1 -1
- package/lib/module/detentBackgrounds.js +21 -0
- package/lib/module/detentBackgrounds.js.map +1 -0
- package/lib/module/fabric/TrueSheetContentViewNativeComponent.ts +1 -1
- package/lib/module/fabric/TrueSheetOverlayViewNativeComponent.ts +12 -0
- package/lib/module/fabric/TrueSheetViewNativeComponent.ts +14 -10
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/mocks/index.js +18 -2
- package/lib/module/mocks/index.js.map +1 -1
- package/lib/module/mocks/navigationExpoRouter.js.map +1 -1
- package/lib/module/navigation/base-types.js +2 -0
- package/lib/module/navigation/base-types.js.map +1 -0
- package/lib/module/navigation/createTrueSheetRouter.js +0 -9
- package/lib/module/navigation/createTrueSheetRouter.js.map +1 -1
- package/lib/module/navigation/expo-router/base-types.js +2 -0
- package/lib/module/navigation/expo-router/base-types.js.map +1 -0
- package/lib/module/navigation/expo-router/index.js +10 -7
- package/lib/module/navigation/expo-router/index.js.map +1 -1
- package/lib/module/navigation/expo-router/types.js +4 -0
- package/lib/module/navigation/expo-router/types.js.map +1 -0
- package/lib/module/navigation/index.js.map +1 -1
- package/lib/module/navigation/screen/useSheetScreenState.js +1 -0
- package/lib/module/navigation/screen/useSheetScreenState.js.map +1 -1
- package/lib/module/web/constants.js +1 -1
- package/lib/module/web/constants.js.map +1 -1
- package/lib/module/web/layout.js +168 -0
- package/lib/module/web/layout.js.map +1 -0
- package/lib/module/web/vaul/constants.js +4 -0
- package/lib/module/web/vaul/constants.js.map +1 -1
- package/lib/module/web/vaul/context.js.map +1 -1
- package/lib/module/web/vaul/helpers.js +1 -0
- package/lib/module/web/vaul/helpers.js.map +1 -1
- package/lib/module/web/vaul/index.js +44 -6
- package/lib/module/web/vaul/index.js.map +1 -1
- package/lib/module/web/vaul/use-snap-points.js +6 -8
- package/lib/module/web/vaul/use-snap-points.js.map +1 -1
- package/lib/typescript/src/TrueSheet.d.ts +6 -0
- package/lib/typescript/src/TrueSheet.d.ts.map +1 -1
- package/lib/typescript/src/TrueSheet.types.d.ts +135 -34
- package/lib/typescript/src/TrueSheet.types.d.ts.map +1 -1
- package/lib/typescript/src/TrueSheet.web.d.ts.map +1 -1
- package/lib/typescript/src/TrueSheetBackground.d.ts +3 -0
- package/lib/typescript/src/TrueSheetBackground.d.ts.map +1 -0
- package/lib/typescript/src/TrueSheetOverlay.d.ts +8 -0
- package/lib/typescript/src/TrueSheetOverlay.d.ts.map +1 -0
- package/lib/typescript/src/TrueSheetOverlay.web.d.ts +8 -0
- package/lib/typescript/src/TrueSheetOverlay.web.d.ts.map +1 -0
- package/lib/typescript/src/TrueSheetPeek.web.d.ts +8 -4
- package/lib/typescript/src/TrueSheetPeek.web.d.ts.map +1 -1
- package/lib/typescript/src/detentBackgrounds.d.ts +10 -0
- package/lib/typescript/src/detentBackgrounds.d.ts.map +1 -0
- package/lib/typescript/src/fabric/TrueSheetOverlayViewNativeComponent.d.ts +6 -0
- package/lib/typescript/src/fabric/TrueSheetOverlayViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/src/fabric/TrueSheetViewNativeComponent.d.ts +11 -7
- package/lib/typescript/src/fabric/TrueSheetViewNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +1 -0
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/mocks/index.d.ts +4 -0
- package/lib/typescript/src/mocks/index.d.ts.map +1 -1
- package/lib/typescript/src/mocks/navigationExpoRouter.d.ts +3 -3
- package/lib/typescript/src/mocks/navigationExpoRouter.d.ts.map +1 -1
- package/lib/typescript/src/navigation/base-types.d.ts +9 -0
- package/lib/typescript/src/navigation/base-types.d.ts.map +1 -0
- package/lib/typescript/src/navigation/createTrueSheetRouter.d.ts +2 -13
- package/lib/typescript/src/navigation/createTrueSheetRouter.d.ts.map +1 -1
- package/lib/typescript/src/navigation/expo-router/base-types.d.ts +8 -0
- package/lib/typescript/src/navigation/expo-router/base-types.d.ts.map +1 -0
- package/lib/typescript/src/navigation/expo-router/index.d.ts +8 -6
- package/lib/typescript/src/navigation/expo-router/index.d.ts.map +1 -1
- package/lib/typescript/src/navigation/expo-router/types.d.ts +44 -0
- package/lib/typescript/src/navigation/expo-router/types.d.ts.map +1 -0
- package/lib/typescript/src/navigation/index.d.ts +3 -4
- package/lib/typescript/src/navigation/index.d.ts.map +1 -1
- package/lib/typescript/src/navigation/screen/useSheetScreenState.d.ts +2 -1
- package/lib/typescript/src/navigation/screen/useSheetScreenState.d.ts.map +1 -1
- package/lib/typescript/src/navigation/types.d.ts +41 -5
- package/lib/typescript/src/navigation/types.d.ts.map +1 -1
- package/lib/typescript/src/web/constants.d.ts +1 -1
- package/lib/typescript/src/web/constants.d.ts.map +1 -1
- package/lib/typescript/src/web/layout.d.ts +19 -0
- package/lib/typescript/src/web/layout.d.ts.map +1 -0
- package/lib/typescript/src/web/vaul/constants.d.ts +1 -0
- package/lib/typescript/src/web/vaul/constants.d.ts.map +1 -1
- package/lib/typescript/src/web/vaul/context.d.ts +1 -0
- package/lib/typescript/src/web/vaul/context.d.ts.map +1 -1
- package/lib/typescript/src/web/vaul/helpers.d.ts +1 -0
- package/lib/typescript/src/web/vaul/helpers.d.ts.map +1 -1
- package/lib/typescript/src/web/vaul/index.d.ts +7 -1
- package/lib/typescript/src/web/vaul/index.d.ts.map +1 -1
- package/lib/typescript/src/web/vaul/use-snap-points.d.ts.map +1 -1
- package/package.json +17 -8
- package/react-native.config.js +1 -0
- package/src/TrueSheet.tsx +206 -48
- package/src/TrueSheet.types.ts +142 -35
- package/src/TrueSheet.web.tsx +270 -290
- package/src/TrueSheetBackground.tsx +17 -0
- package/src/TrueSheetOverlay.tsx +24 -0
- package/src/TrueSheetOverlay.web.tsx +33 -0
- package/src/TrueSheetPeek.web.tsx +25 -23
- package/src/detentBackgrounds.ts +24 -0
- package/src/fabric/TrueSheetContentViewNativeComponent.ts +1 -1
- package/src/fabric/TrueSheetOverlayViewNativeComponent.ts +12 -0
- package/src/fabric/TrueSheetViewNativeComponent.ts +14 -10
- package/src/index.ts +1 -0
- package/src/mocks/index.ts +17 -2
- package/src/mocks/navigationExpoRouter.ts +6 -5
- package/src/navigation/base-types.ts +20 -0
- package/src/navigation/createTrueSheetRouter.ts +5 -33
- package/src/navigation/expo-router/base-types.ts +18 -0
- package/src/navigation/expo-router/index.ts +28 -30
- package/src/navigation/expo-router/types.ts +116 -0
- package/src/navigation/index.ts +6 -7
- package/src/navigation/screen/useSheetScreenState.ts +2 -0
- package/src/navigation/types.ts +75 -22
- package/src/web/constants.ts +1 -1
- package/src/web/layout.ts +196 -0
- package/src/web/vaul/constants.ts +4 -0
- package/src/web/vaul/context.ts +1 -0
- package/src/web/vaul/helpers.ts +5 -0
- package/src/web/vaul/index.tsx +67 -5
- package/src/web/vaul/use-snap-points.ts +6 -14
package/ios/TrueSheetView.mm
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
#import "TrueSheetContentView.h"
|
|
14
14
|
#import "TrueSheetFooterView.h"
|
|
15
15
|
#import "TrueSheetModule.h"
|
|
16
|
+
#import "TrueSheetOverlayView.h"
|
|
16
17
|
#import "TrueSheetViewController.h"
|
|
17
18
|
#import "core/RNScreensEventObserver.h"
|
|
18
19
|
#import "events/TrueSheetDragEvents.h"
|
|
@@ -53,7 +54,7 @@ using namespace facebook::react;
|
|
|
53
54
|
NSInteger _initialDetentIndex;
|
|
54
55
|
TrueSheetViewInsetAdjustment _insetAdjustment;
|
|
55
56
|
ScrollableOptions *_scrollableOptions;
|
|
56
|
-
|
|
57
|
+
NSInteger _scrollableHandle;
|
|
57
58
|
BOOL _initialDetentAnimated;
|
|
58
59
|
BOOL _isSheetUpdatePending;
|
|
59
60
|
BOOL _pendingLayoutUpdate;
|
|
@@ -110,18 +111,72 @@ using namespace facebook::react;
|
|
|
110
111
|
return;
|
|
111
112
|
}
|
|
112
113
|
|
|
113
|
-
|
|
114
|
-
|
|
114
|
+
[self presentInitialIfNeeded];
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// JS holds initialDetentIndex back one commit so effect-driven content (e.g. a
|
|
118
|
+
// navigation footer set via setOptions) commits together with it — by the time
|
|
119
|
+
// the prop lands the tree is final and the sheet presents at its final height.
|
|
120
|
+
// Called from didMoveToWindow (re-attach) and finalizeUpdates (the prop
|
|
121
|
+
// arriving after attach, which didMoveToWindow won't re-fire for).
|
|
122
|
+
- (void)presentInitialIfNeeded {
|
|
123
|
+
if (_initialDetentIndex < 0 || _didInitiallyPresent)
|
|
124
|
+
return;
|
|
125
|
+
|
|
126
|
+
UIViewController *vc = [self findPresentingViewController];
|
|
115
127
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
128
|
+
// Only present if the view controller is in the same window
|
|
129
|
+
if (!vc || vc.view.window != self.window) {
|
|
130
|
+
// Animate next time when sheet finally moves to the correct window
|
|
131
|
+
_initialDetentAnimated = YES;
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// A sheet still animating out of the presenter (e.g. our own controller,
|
|
136
|
+
// recycled mid-dismissal) blocks presentation — retry once its transition ends.
|
|
137
|
+
UIViewController *dismissing = vc.presentedViewController;
|
|
138
|
+
if (dismissing && dismissing.isBeingDismissed) {
|
|
139
|
+
_initialDetentAnimated = YES;
|
|
140
|
+
|
|
141
|
+
__weak __typeof(self) weakSelf = self;
|
|
142
|
+
void (^retry)(void) = ^{
|
|
143
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
144
|
+
[weakSelf presentInitialIfNeeded];
|
|
145
|
+
});
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
id<UIViewControllerTransitionCoordinator> coordinator = dismissing.transitionCoordinator;
|
|
149
|
+
if (coordinator) {
|
|
150
|
+
[coordinator animateAlongsideTransition:nil
|
|
151
|
+
completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {
|
|
152
|
+
retry();
|
|
153
|
+
}];
|
|
120
154
|
} else {
|
|
121
|
-
|
|
122
|
-
_initialDetentAnimated = YES;
|
|
155
|
+
retry();
|
|
123
156
|
}
|
|
157
|
+
return;
|
|
124
158
|
}
|
|
159
|
+
|
|
160
|
+
_didInitiallyPresent = YES;
|
|
161
|
+
|
|
162
|
+
// Deferred a runloop turn so sibling mounts from the current transaction
|
|
163
|
+
// (e.g. a footer committed alongside the prop) land before measuring.
|
|
164
|
+
__weak __typeof(self) weakSelf = self;
|
|
165
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
166
|
+
__typeof(self) strongSelf = weakSelf;
|
|
167
|
+
if (!strongSelf || strongSelf->_controller.isPresented || strongSelf->_controller.isBeingPresented)
|
|
168
|
+
return;
|
|
169
|
+
|
|
170
|
+
[strongSelf presentAtIndex:strongSelf->_initialDetentIndex
|
|
171
|
+
animated:strongSelf->_initialDetentAnimated
|
|
172
|
+
completion:^(BOOL success, NSError *_Nullable error) {
|
|
173
|
+
// Present can fail if the view detached during this turn —
|
|
174
|
+
// reset so the next attach/prop update retries.
|
|
175
|
+
if (!success) {
|
|
176
|
+
strongSelf->_didInitiallyPresent = NO;
|
|
177
|
+
}
|
|
178
|
+
}];
|
|
179
|
+
});
|
|
125
180
|
}
|
|
126
181
|
|
|
127
182
|
- (void)dealloc {
|
|
@@ -146,8 +201,6 @@ using namespace facebook::react;
|
|
|
146
201
|
|
|
147
202
|
[_snapshotView removeFromSuperview];
|
|
148
203
|
_snapshotView = nil;
|
|
149
|
-
|
|
150
|
-
[TrueSheetModule unregisterViewWithTag:@(self.tag)];
|
|
151
204
|
}
|
|
152
205
|
|
|
153
206
|
#pragma mark - RCTComponentViewProtocol
|
|
@@ -163,12 +216,8 @@ using namespace facebook::react;
|
|
|
163
216
|
|
|
164
217
|
// Detents (-1 represents "auto")
|
|
165
218
|
NSMutableArray *detents = [NSMutableArray new];
|
|
166
|
-
_hasAutoDetent = NO;
|
|
167
219
|
for (const auto &detent : newProps.detents) {
|
|
168
220
|
[detents addObject:@(detent)];
|
|
169
|
-
if (detent == -1) {
|
|
170
|
-
_hasAutoDetent = YES;
|
|
171
|
-
}
|
|
172
221
|
}
|
|
173
222
|
|
|
174
223
|
if (oldProps) {
|
|
@@ -187,14 +236,29 @@ using namespace facebook::react;
|
|
|
187
236
|
// Background color
|
|
188
237
|
_controller.backgroundColor = RCTUIColorFromSharedColor(newProps.backgroundColor);
|
|
189
238
|
|
|
239
|
+
NSMutableArray<NSDictionary *> *detentBackgrounds = [NSMutableArray new];
|
|
240
|
+
ContextContainer contextContainer;
|
|
241
|
+
PropsParserContext parserContext{-1, contextContainer};
|
|
242
|
+
for (const auto &entry : newProps.detentBackgrounds) {
|
|
243
|
+
NSMutableDictionary *background = [NSMutableDictionary new];
|
|
244
|
+
UIColor *color = RCTUIColorFromSharedColor(entry.color);
|
|
245
|
+
if (color) {
|
|
246
|
+
background[@"color"] = color;
|
|
247
|
+
}
|
|
248
|
+
if (!entry.blur.empty()) {
|
|
249
|
+
auto blur = TrueSheetViewBackgroundBlur::None;
|
|
250
|
+
fromRawValue(parserContext, RawValue(entry.blur), blur);
|
|
251
|
+
background[@"blur"] = @(static_cast<int>(blur));
|
|
252
|
+
}
|
|
253
|
+
[detentBackgrounds addObject:background];
|
|
254
|
+
}
|
|
255
|
+
if (![_controller.detentBackgrounds isEqualToArray:detentBackgrounds]) {
|
|
256
|
+
_controller.detentBackgrounds = detentBackgrounds;
|
|
257
|
+
}
|
|
258
|
+
|
|
190
259
|
// Blur tint
|
|
191
260
|
_controller.backgroundBlur = newProps.backgroundBlur;
|
|
192
261
|
|
|
193
|
-
// Blur options
|
|
194
|
-
const auto &blurOpts = newProps.blurOptions;
|
|
195
|
-
_controller.blurIntensity = blurOpts.intensity >= 0 ? @(blurOpts.intensity) : nil;
|
|
196
|
-
_controller.blurInteraction = blurOpts.interaction;
|
|
197
|
-
|
|
198
262
|
// Corner radius
|
|
199
263
|
_controller.cornerRadius = newProps.cornerRadius < 0 ? nil : @(newProps.cornerRadius);
|
|
200
264
|
|
|
@@ -204,8 +268,7 @@ using namespace facebook::react;
|
|
|
204
268
|
// Content width
|
|
205
269
|
_controller.maxContentWidth = newProps.maxContentWidth != 0.0 ? @(newProps.maxContentWidth) : nil;
|
|
206
270
|
|
|
207
|
-
|
|
208
|
-
_controller.anchor = newProps.anchor;
|
|
271
|
+
_controller.placement = newProps.placement;
|
|
209
272
|
|
|
210
273
|
_controller.grabber = newProps.grabber;
|
|
211
274
|
|
|
@@ -248,33 +311,38 @@ using namespace facebook::react;
|
|
|
248
311
|
_initialDetentIndex = newProps.initialDetentIndex;
|
|
249
312
|
_initialDetentAnimated = newProps.initialDetentAnimated;
|
|
250
313
|
|
|
251
|
-
|
|
252
|
-
BOOL scrollingExpandsSheet = scrollableOpts.scrollingExpandsSheet;
|
|
253
|
-
auto topEdgeEffect = scrollableOpts.topScrollEdgeEffect;
|
|
254
|
-
auto bottomEdgeEffect = scrollableOpts.bottomScrollEdgeEffect;
|
|
255
|
-
BOOL hasScrollableOptions = scrollableOpts.keyboardScrollOffset > 0 || !scrollingExpandsSheet ||
|
|
256
|
-
topEdgeEffect != TrueSheetViewTopScrollEdgeEffect::Hidden ||
|
|
257
|
-
bottomEdgeEffect != TrueSheetViewBottomScrollEdgeEffect::Hidden;
|
|
258
|
-
|
|
259
|
-
if (hasScrollableOptions) {
|
|
260
|
-
ScrollableOptions *options = [[ScrollableOptions alloc] init];
|
|
261
|
-
options.keyboardScrollOffset = scrollableOpts.keyboardScrollOffset;
|
|
262
|
-
options.scrollingExpandsSheet = scrollingExpandsSheet;
|
|
263
|
-
options.topScrollEdgeEffect = topEdgeEffect;
|
|
264
|
-
options.bottomScrollEdgeEffect = bottomEdgeEffect;
|
|
265
|
-
_scrollableOptions = options;
|
|
266
|
-
} else {
|
|
267
|
-
_scrollableOptions = nil;
|
|
268
|
-
}
|
|
314
|
+
_scrollableHandle = newProps.scrollableHandle;
|
|
269
315
|
|
|
270
|
-
|
|
316
|
+
const auto &scrollableOpts = newProps.scrollableOptions;
|
|
317
|
+
ScrollableOptions *options = [[ScrollableOptions alloc] init];
|
|
318
|
+
options.contentInsetAdjustment = scrollableOpts.contentInsetAdjustment;
|
|
319
|
+
options.keyboardScrollOffset = scrollableOpts.keyboardScrollOffset;
|
|
320
|
+
options.keyboardOffset = scrollableOpts.keyboardOffset;
|
|
321
|
+
options.scrollingExpandsSheet = scrollableOpts.scrollingExpandsSheet;
|
|
322
|
+
options.topScrollEdgeEffect = scrollableOpts.topScrollEdgeEffect;
|
|
323
|
+
options.bottomScrollEdgeEffect = scrollableOpts.bottomScrollEdgeEffect;
|
|
324
|
+
|
|
325
|
+
// nil while every option is at its default
|
|
326
|
+
BOOL hasScrollableOptions = options.keyboardScrollOffset > 0 || options.keyboardOffset != 0 ||
|
|
327
|
+
!options.scrollingExpandsSheet ||
|
|
328
|
+
options.contentInsetAdjustment != TrueSheetViewContentInsetAdjustment::Automatic ||
|
|
329
|
+
options.topScrollEdgeEffect != TrueSheetViewTopScrollEdgeEffect::Hidden ||
|
|
330
|
+
options.bottomScrollEdgeEffect != TrueSheetViewBottomScrollEdgeEffect::Hidden;
|
|
331
|
+
_scrollableOptions = hasScrollableOptions ? options : nil;
|
|
332
|
+
|
|
333
|
+
_controller.scrollingExpandsSheet = options.scrollingExpandsSheet;
|
|
271
334
|
|
|
272
335
|
_controller.absoluteHeader = newProps.headerOptions.position == TrueSheetViewPosition::Absolute;
|
|
273
336
|
_controller.absoluteFooter = newProps.footerOptions.footerPosition == TrueSheetViewFooterPosition::Absolute;
|
|
337
|
+
_controller.footerInsetAdjustment =
|
|
338
|
+
options.footerInsetAdjustment && _controller.absoluteFooter && _scrollableHandle > 0;
|
|
274
339
|
|
|
275
340
|
CGFloat footerKeyboardOffset = newProps.footerOptions.keyboardOffset;
|
|
276
|
-
|
|
341
|
+
BOOL footerAvoidsKeyboard = newProps.footerOptions.avoidKeyboard;
|
|
342
|
+
if (_controller.footerKeyboardOffset != footerKeyboardOffset ||
|
|
343
|
+
_controller.footerAvoidsKeyboard != footerAvoidsKeyboard) {
|
|
277
344
|
_controller.footerKeyboardOffset = footerKeyboardOffset;
|
|
345
|
+
_controller.footerAvoidsKeyboard = footerAvoidsKeyboard;
|
|
278
346
|
[_containerView updateFooterKeyboardOffset];
|
|
279
347
|
}
|
|
280
348
|
|
|
@@ -342,13 +410,47 @@ using namespace facebook::react;
|
|
|
342
410
|
_pendingPropsUpdate = YES;
|
|
343
411
|
} else if (_initialDetentIndex >= 0) {
|
|
344
412
|
_pendingLayoutUpdate = NO;
|
|
413
|
+
if (self.window) {
|
|
414
|
+
[self presentInitialIfNeeded];
|
|
415
|
+
}
|
|
345
416
|
}
|
|
346
417
|
}
|
|
347
418
|
|
|
348
419
|
- (void)prepareForRecycle {
|
|
349
420
|
[super prepareForRecycle];
|
|
350
421
|
|
|
351
|
-
|
|
422
|
+
// Pooled mid-dismissal: the next mount can reuse this host — and its
|
|
423
|
+
// controller — while the previous sheet is still animating out. Detach until
|
|
424
|
+
// that transition ends so its tail (didBlur, didDismiss, position) can't reach
|
|
425
|
+
// the new mount, then hand the controller back and let auto-present retry.
|
|
426
|
+
if (_controller.isBeingDismissed) {
|
|
427
|
+
_controller.delegate = nil;
|
|
428
|
+
|
|
429
|
+
__weak __typeof(self) weakSelf = self;
|
|
430
|
+
void (^reattach)(void) = ^{
|
|
431
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
432
|
+
__typeof(self) strongSelf = weakSelf;
|
|
433
|
+
if (!strongSelf)
|
|
434
|
+
return;
|
|
435
|
+
|
|
436
|
+
strongSelf->_controller.delegate = strongSelf;
|
|
437
|
+
strongSelf->_controller.activeDetentIndex = -1;
|
|
438
|
+
if (strongSelf.window) {
|
|
439
|
+
[strongSelf presentInitialIfNeeded];
|
|
440
|
+
}
|
|
441
|
+
});
|
|
442
|
+
};
|
|
443
|
+
|
|
444
|
+
id<UIViewControllerTransitionCoordinator> coordinator = _controller.transitionCoordinator;
|
|
445
|
+
if (coordinator) {
|
|
446
|
+
[coordinator animateAlongsideTransition:nil
|
|
447
|
+
completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {
|
|
448
|
+
reattach();
|
|
449
|
+
}];
|
|
450
|
+
} else {
|
|
451
|
+
reattach();
|
|
452
|
+
}
|
|
453
|
+
}
|
|
352
454
|
|
|
353
455
|
_lastStateSize = CGSizeZero;
|
|
354
456
|
_didInitiallyPresent = NO;
|
|
@@ -389,7 +491,6 @@ using namespace facebook::react;
|
|
|
389
491
|
[_touchHandler attachToView:_containerView];
|
|
390
492
|
[_controller.view addSubview:_containerView];
|
|
391
493
|
[_controller.view bringSubviewToFront:_containerView];
|
|
392
|
-
_containerView.accessibilityViewIsModal = YES;
|
|
393
494
|
_controller.accessibilityContentView = _containerView;
|
|
394
495
|
[_controller setupAccessibilityContainer];
|
|
395
496
|
|
|
@@ -403,9 +504,8 @@ using namespace facebook::react;
|
|
|
403
504
|
_controller.headerHeight = @(headerHeight);
|
|
404
505
|
}
|
|
405
506
|
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
_controller.footerHeight = @(footerHeight);
|
|
507
|
+
if ([_containerView footerHeight] > 0) {
|
|
508
|
+
[self syncFooterMetrics];
|
|
409
509
|
}
|
|
410
510
|
|
|
411
511
|
CGFloat peekContentHeight = [_containerView peekContentHeight];
|
|
@@ -471,7 +571,7 @@ using namespace facebook::react;
|
|
|
471
571
|
[_controller setupSheetSizing];
|
|
472
572
|
[_controller setupSheetProps];
|
|
473
573
|
|
|
474
|
-
//
|
|
574
|
+
// Detect before measuring so a first-time detection doesn't shift sizes mid-animation.
|
|
475
575
|
[self setupScrollable];
|
|
476
576
|
|
|
477
577
|
// Measure synchronously so the presentation starts at the right height —
|
|
@@ -480,24 +580,41 @@ using namespace facebook::react;
|
|
|
480
580
|
if (_containerView) {
|
|
481
581
|
_controller.contentHeight = @([_containerView contentHeight]);
|
|
482
582
|
_controller.headerHeight = @([_containerView headerHeight]);
|
|
483
|
-
|
|
583
|
+
[self syncFooterMetrics];
|
|
484
584
|
_controller.peekContentHeight = @([_containerView peekContentHeight]);
|
|
485
585
|
}
|
|
486
586
|
_pendingSizeChange = NO;
|
|
487
587
|
|
|
588
|
+
[self refreshFooterBottomInset];
|
|
488
589
|
[_controller setupSheetDetents];
|
|
489
590
|
[_controller setupActiveDetentWithIndex:index];
|
|
490
591
|
|
|
491
592
|
[_screensEventObserver capturePresenterScreenFromView:self];
|
|
492
593
|
[_screensEventObserver startObservingWithState:_state.get()->getData()];
|
|
493
594
|
|
|
595
|
+
UIWindow *window = presentingViewController.view.window;
|
|
494
596
|
[presentingViewController presentViewController:_controller
|
|
495
597
|
animated:animated
|
|
496
598
|
completion:^{
|
|
599
|
+
[TrueSheetOverlayView bringOverlaysToFrontInWindow:window];
|
|
497
600
|
if (completion) {
|
|
498
601
|
completion(YES, nil);
|
|
499
602
|
}
|
|
500
603
|
}];
|
|
604
|
+
|
|
605
|
+
// Presenting adds the sheet's transition view on top of the window once the
|
|
606
|
+
// transition starts — re-front overlays alongside it so the first frame is
|
|
607
|
+
// already ordered (and again on completion in case the transition was queued)
|
|
608
|
+
id<UIViewControllerTransitionCoordinator> coordinator = _controller.transitionCoordinator;
|
|
609
|
+
if (coordinator) {
|
|
610
|
+
[coordinator
|
|
611
|
+
animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) {
|
|
612
|
+
[TrueSheetOverlayView bringOverlaysToFrontInWindow:window];
|
|
613
|
+
}
|
|
614
|
+
completion:nil];
|
|
615
|
+
} else {
|
|
616
|
+
[TrueSheetOverlayView bringOverlaysToFrontInWindow:window];
|
|
617
|
+
}
|
|
501
618
|
}
|
|
502
619
|
|
|
503
620
|
- (void)resizeToIndex:(NSInteger)index completion:(nullable TrueSheetCompletionBlock)completion {
|
|
@@ -583,6 +700,10 @@ using namespace facebook::react;
|
|
|
583
700
|
* Debounced sheet update to handle rapid content/header size changes.
|
|
584
701
|
*/
|
|
585
702
|
- (void)setupSheetDetentsForSizeChange {
|
|
703
|
+
// Keep the footer's absorbed inset in sync with the latest measured heights
|
|
704
|
+
// even before presenting, so the sheet presents at its final size.
|
|
705
|
+
[self refreshFooterBottomInset];
|
|
706
|
+
|
|
586
707
|
// Retargeting the in-flight presentation makes UIKit snap the whole stack
|
|
587
708
|
// (including the sheet behind) instead of animating. Defer to didPresent —
|
|
588
709
|
// presentAtIndex measured synchronously, so this is usually a no-op.
|
|
@@ -610,6 +731,7 @@ using namespace facebook::react;
|
|
|
610
731
|
// Refresh here (not just on peek size events) since the peek's offset
|
|
611
732
|
// within the content can change without its own size changing.
|
|
612
733
|
self->_controller.peekContentHeight = @([self->_containerView peekContentHeight]);
|
|
734
|
+
[self refreshFooterBottomInset];
|
|
613
735
|
[self->_controller setupSheetDetentsForSizeChange];
|
|
614
736
|
});
|
|
615
737
|
}
|
|
@@ -625,7 +747,7 @@ using namespace facebook::react;
|
|
|
625
747
|
}
|
|
626
748
|
|
|
627
749
|
- (void)containerViewFooterDidChangeSize:(CGSize)newSize {
|
|
628
|
-
|
|
750
|
+
[self syncFooterMetrics];
|
|
629
751
|
[self setupSheetDetentsForSizeChange];
|
|
630
752
|
[_controller setupAccessibilityContainer];
|
|
631
753
|
}
|
|
@@ -634,7 +756,7 @@ using namespace facebook::react;
|
|
|
634
756
|
[self setupSheetDetentsForSizeChange];
|
|
635
757
|
}
|
|
636
758
|
|
|
637
|
-
// When the ScrollView changes (e.g. conditional remount), re-
|
|
759
|
+
// When the ScrollView changes (e.g. conditional remount), re-detect the new ScrollView.
|
|
638
760
|
- (void)containerViewScrollViewDidChange {
|
|
639
761
|
[self setupScrollable];
|
|
640
762
|
}
|
|
@@ -687,6 +809,10 @@ using namespace facebook::react;
|
|
|
687
809
|
}
|
|
688
810
|
}
|
|
689
811
|
|
|
812
|
+
- (void)viewControllerDidAttemptDismiss {
|
|
813
|
+
[TrueSheetLifecycleEvents emitDismissAttempt:_eventEmitter];
|
|
814
|
+
}
|
|
815
|
+
|
|
690
816
|
- (void)viewControllerDidDismiss {
|
|
691
817
|
[_containerView cleanupKeyboardObserver];
|
|
692
818
|
if (!_dismissedByNavigation) {
|
|
@@ -716,6 +842,11 @@ using namespace facebook::react;
|
|
|
716
842
|
[self updateStateWithSize:size];
|
|
717
843
|
}
|
|
718
844
|
|
|
845
|
+
- (void)viewControllerSafeAreaInsetsDidChange {
|
|
846
|
+
[self refreshFooterBottomInset];
|
|
847
|
+
[_containerView updateFooterKeyboardOffset];
|
|
848
|
+
}
|
|
849
|
+
|
|
719
850
|
- (void)viewControllerWillFocus {
|
|
720
851
|
[TrueSheetFocusEvents emitWillFocus:_eventEmitter];
|
|
721
852
|
}
|
|
@@ -781,16 +912,41 @@ using namespace facebook::react;
|
|
|
781
912
|
if (!_containerView)
|
|
782
913
|
return;
|
|
783
914
|
|
|
784
|
-
_containerView.insetAdjustment = _insetAdjustment;
|
|
785
915
|
_containerView.scrollableOptions = _scrollableOptions;
|
|
786
|
-
_containerView.
|
|
787
|
-
_containerView.
|
|
916
|
+
_containerView.scrollableHandle = _scrollableHandle;
|
|
917
|
+
_containerView.safeAreaInsetAdjustment = (_scrollableOptions ? _scrollableOptions.safeAreaInsetAdjustment : YES) &&
|
|
918
|
+
_insetAdjustment == TrueSheetViewInsetAdjustment::Automatic;
|
|
919
|
+
_containerView.footerInsetAdjustment = _controller.footerInsetAdjustment;
|
|
920
|
+
[self refreshFooterBottomInset];
|
|
788
921
|
[_containerView setupScrollable];
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
// footerHeight and appliedFooterBottomInset must stay paired — detent math
|
|
925
|
+
// subtracts exactly the inset baked into the measured footer height (see
|
|
926
|
+
// autoDetentBottomInset/peekDetentBottomInset).
|
|
927
|
+
- (void)syncFooterMetrics {
|
|
928
|
+
_controller.footerHeight = @([_containerView footerHeight]);
|
|
929
|
+
_controller.appliedFooterBottomInset = [_containerView footerAppliedBottomInset];
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
// Recomputes the inset the footer absorbs and pushes it down. The inset
|
|
933
|
+
// depends on measured heights and detents (see maxNaturalDetentHeight), so
|
|
934
|
+
// this runs on size and detent changes — not just prop updates.
|
|
935
|
+
- (void)refreshFooterBottomInset {
|
|
936
|
+
if (!_containerView)
|
|
937
|
+
return;
|
|
938
|
+
|
|
939
|
+
// appliedFooterBottomInset is NOT set here — it tracks what's actually
|
|
940
|
+
// baked into the footer's measured height (reported with its layout), not
|
|
941
|
+
// what was just pushed. Setting it at push time desyncs the pair and lets
|
|
942
|
+
// a seeded inset read as natural content height (see maxNaturalDetentHeight).
|
|
943
|
+
CGFloat inset = _controller.footerBottomInset;
|
|
944
|
+
_containerView.footerBottomInset = inset;
|
|
789
945
|
|
|
790
946
|
// Publish the inset so a footer set later (e.g. navigation setOptions) is
|
|
791
947
|
// padded on its very first layout instead of resizing the sheet twice.
|
|
792
948
|
if (_insetAdjustment == TrueSheetViewInsetAdjustment::Automatic) {
|
|
793
|
-
TrueSheetInsets::setBottomSafeArea(
|
|
949
|
+
TrueSheetInsets::setBottomSafeArea(inset);
|
|
794
950
|
}
|
|
795
951
|
}
|
|
796
952
|
|
|
@@ -801,6 +957,7 @@ using namespace facebook::react;
|
|
|
801
957
|
if (_pendingDetents) {
|
|
802
958
|
_controller.detents = _pendingDetents;
|
|
803
959
|
_pendingDetents = nil;
|
|
960
|
+
[self refreshFooterBottomInset];
|
|
804
961
|
}
|
|
805
962
|
|
|
806
963
|
UIView *presenterView = _controller.presentingViewController.view;
|
|
@@ -26,6 +26,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
26
26
|
- (void)viewControllerDidPresentAtIndex:(NSInteger)index position:(CGFloat)position detent:(CGFloat)detent;
|
|
27
27
|
- (void)viewControllerWillDismiss;
|
|
28
28
|
- (void)viewControllerDidDismiss;
|
|
29
|
+
- (void)viewControllerDidAttemptDismiss;
|
|
29
30
|
- (void)viewControllerDidChangeDetent:(NSInteger)index position:(CGFloat)position detent:(CGFloat)detent;
|
|
30
31
|
- (void)viewControllerDidDrag:(UIGestureRecognizerState)state
|
|
31
32
|
index:(NSInteger)index
|
|
@@ -36,6 +37,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
36
37
|
detent:(CGFloat)detent
|
|
37
38
|
realtime:(BOOL)realtime;
|
|
38
39
|
- (void)viewControllerDidChangeSize:(CGSize)size;
|
|
40
|
+
- (void)viewControllerSafeAreaInsetsDidChange;
|
|
39
41
|
- (void)viewControllerWillFocus;
|
|
40
42
|
- (void)viewControllerDidFocus;
|
|
41
43
|
- (void)viewControllerWillBlur;
|
|
@@ -53,6 +55,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
53
55
|
|
|
54
56
|
@property (nonatomic, weak, nullable) id<TrueSheetViewControllerDelegate> delegate;
|
|
55
57
|
@property (nonatomic, strong) NSArray<NSNumber *> *detents;
|
|
58
|
+
@property (nonatomic, copy) NSArray<NSDictionary *> *detentBackgrounds;
|
|
56
59
|
@property (nonatomic, strong, nullable) NSNumber *maxContentHeight;
|
|
57
60
|
@property (nonatomic, strong, nullable) NSNumber *maxContentWidth;
|
|
58
61
|
@property (nonatomic, strong, nullable) NSNumber *contentHeight;
|
|
@@ -60,6 +63,13 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
60
63
|
@property (nonatomic, assign) BOOL absoluteHeader;
|
|
61
64
|
@property (nonatomic, strong, nullable) NSNumber *footerHeight;
|
|
62
65
|
@property (nonatomic, assign) BOOL absoluteFooter;
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* YES while the plugged scrollable is padded by the absolute footer's height
|
|
69
|
+
* (see ScrollableOptions.contentInsetAdjustment) — the footer then counts
|
|
70
|
+
* toward the auto detent like a relative one, so the content ends above it.
|
|
71
|
+
*/
|
|
72
|
+
@property (nonatomic, assign) BOOL footerInsetAdjustment;
|
|
63
73
|
@property (nonatomic, strong, nullable) NSNumber *peekContentHeight;
|
|
64
74
|
@property (nonatomic, strong, nullable) UIColor *backgroundColor;
|
|
65
75
|
@property (nonatomic, strong, nullable) NSNumber *cornerRadius;
|
|
@@ -70,13 +80,17 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
70
80
|
@property (nonatomic, assign) BOOL dimmed;
|
|
71
81
|
@property (nonatomic, strong, nullable) NSNumber *dimmedDetentIndex;
|
|
72
82
|
@property (nonatomic, assign) facebook::react::TrueSheetViewBackgroundBlur backgroundBlur;
|
|
73
|
-
@property (nonatomic, strong, nullable) NSNumber *blurIntensity;
|
|
74
|
-
@property (nonatomic, assign) BOOL blurInteraction;
|
|
75
83
|
@property (nonatomic, assign) facebook::react::TrueSheetViewPresentation presentation;
|
|
76
|
-
@property (nonatomic, assign) facebook::react::
|
|
84
|
+
@property (nonatomic, assign) facebook::react::TrueSheetViewPlacement placement;
|
|
77
85
|
@property (nonatomic, assign) facebook::react::TrueSheetViewInsetAdjustment insetAdjustment;
|
|
78
86
|
@property (nonatomic, assign) BOOL scrollingExpandsSheet;
|
|
79
87
|
@property (nonatomic, assign) CGFloat footerKeyboardOffset;
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* NO keeps an absolute footer pinned to the sheet's bottom edge behind the
|
|
91
|
+
* keyboard instead of rising above it.
|
|
92
|
+
*/
|
|
93
|
+
@property (nonatomic, assign) BOOL footerAvoidsKeyboard;
|
|
80
94
|
@property (nonatomic, assign) BOOL dismissible;
|
|
81
95
|
@property (nonatomic, assign) BOOL isPresented;
|
|
82
96
|
@property (nonatomic, assign) NSInteger activeDetentIndex;
|
|
@@ -87,6 +101,12 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
87
101
|
* ~keyboardHeight into the learned offset.
|
|
88
102
|
*/
|
|
89
103
|
@property (nonatomic, assign) BOOL keyboardSheetGrown;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Target keyboard height, set as soon as the keyboard frame change is
|
|
107
|
+
* announced — ahead of the grow/shrink animation, unlike keyboardSheetGrown.
|
|
108
|
+
*/
|
|
109
|
+
@property (nonatomic, assign) CGFloat keyboardHeight;
|
|
90
110
|
@property (nonatomic, readonly) BOOL isTopmostPresentedController;
|
|
91
111
|
@property (nonatomic, readonly) BOOL isStackedBehindChild;
|
|
92
112
|
@property (nonatomic, weak, nullable) UIView *accessibilityContentView;
|
|
@@ -99,6 +119,14 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
99
119
|
*/
|
|
100
120
|
@property (nonatomic, readonly) CGFloat footerBottomInset;
|
|
101
121
|
|
|
122
|
+
/**
|
|
123
|
+
* The inset currently baked into the footer's measured height, reported
|
|
124
|
+
* alongside its layout (see TrueSheetFooterView.appliedBottomInset). Detent
|
|
125
|
+
* resolution subtracts this exact value so the baked inset is never
|
|
126
|
+
* double-counted.
|
|
127
|
+
*/
|
|
128
|
+
@property (nonatomic, assign) CGFloat appliedFooterBottomInset;
|
|
129
|
+
|
|
102
130
|
- (void)setupAccessibilityContainer;
|
|
103
131
|
- (void)applyActiveDetent;
|
|
104
132
|
- (void)setupActiveDetentWithIndex:(NSInteger)index;
|