@apexnative/navigation 1.0.0-alpha.3 → 1.0.0-alpha.4
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/CHANGELOG.md +9 -0
- package/android/CLAUDE.md +17 -7
- package/android/CORE.md +8 -3
- package/android/RECIPES.md +9 -3
- package/android/src/main/java/dev/apexnative/navigation/NavigationApplication.kt +34 -13
- package/android/src/main/java/dev/apexnative/navigation/layout/LayoutChecks.kt +5 -1
- package/android/src/main/java/dev/apexnative/navigation/layout/LayoutNode.kt +6 -2
- package/android/src/main/java/dev/apexnative/navigation/nativescreen/NativeScreenContext.kt +2 -2
- package/android/src/main/java/dev/apexnative/navigation/options/ButtonMenuOptions.kt +2 -2
- package/android/src/main/java/dev/apexnative/navigation/options/ButtonOptions.kt +2 -2
- package/android/src/main/java/dev/apexnative/navigation/options/OptionsCache.kt +8 -4
- package/android/src/main/java/dev/apexnative/navigation/options/UserChoices.kt +159 -0
- package/android/src/main/java/dev/apexnative/navigation/react/CommandAnswer.kt +2 -24
- package/android/src/main/java/dev/apexnative/navigation/react/CommandContract.kt +59 -0
- package/android/src/main/java/dev/apexnative/navigation/react/Hinge.kt +27 -19
- package/android/src/main/java/dev/apexnative/navigation/react/NavigationTurboModule.kt +5 -4
- package/android/src/main/java/dev/apexnative/navigation/react/PendingCalls.kt +48 -0
- package/android/src/main/java/dev/apexnative/navigation/react/events/AppearanceDispatcher.kt +17 -7
- package/android/src/main/java/dev/apexnative/navigation/slots/SlotContainers.kt +10 -7
- package/android/src/main/java/dev/apexnative/navigation/slots/SlotView.kt +4 -3
- package/android/src/main/java/dev/apexnative/navigation/slots/SlotViews.kt +40 -0
- package/android/src/main/java/dev/apexnative/navigation/utils/ImageKey.kt +66 -0
- package/android/src/main/java/dev/apexnative/navigation/utils/ImageLoader.kt +7 -89
- package/android/src/main/java/dev/apexnative/navigation/utils/ImageRequests.kt +76 -0
- package/android/src/main/java/dev/apexnative/navigation/utils/OptionImages.kt +262 -0
- package/android/src/main/java/dev/apexnative/navigation/utils/ViewController.kt +3 -1
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/AppliedTabCalls.kt +49 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/BottomTabsController.kt +16 -6
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/BottomTabsPresenter.kt +25 -24
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ContentReadiness.kt +1 -1
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/RenderWait.kt +27 -7
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalCoordinator.kt +5 -5
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/Navigator.kt +4 -3
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/RootCoordinator.kt +6 -3
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/overlay/OverlayCoordinator.kt +8 -8
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/parent/Capabilities.kt +11 -4
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/sidemenu/SideMenuController.kt +1 -1
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/splitview/SplitPanes.kt +23 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/splitview/SplitViewController.kt +58 -15
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackCommands.kt +28 -18
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackController.kt +16 -7
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackDisplay.kt +2 -1
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackQueue.kt +85 -29
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackViews.kt +2 -2
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/fab/FabPresenter.kt +7 -5
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/search/StackSearchPresenter.kt +3 -3
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/MenuChecks.kt +13 -56
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/TopBarPresenter.kt +10 -2
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/viewcontroller/ViewController.kt +56 -21
- package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/BottomTabs.kt +4 -2
- package/android/src/main/java/dev/apexnative/navigation/views/stack/fab/Fab.kt +14 -10
- package/cli/doctor/checks/app.js +61 -13
- package/cli/migrate/native.js +18 -0
- package/cli/setup/source.js +2 -1
- package/cli/setup/steps/mainApplication.js +134 -19
- package/docs-md/architecture/transitions.md +6 -7
- package/docs-md/help/glossary.md +1 -1
- package/docs-md/help/troubleshooting.md +20 -3
- package/docs-md/index.json +4 -0
- package/docs-md/migration/from-react-native-navigation.md +8 -2
- package/docs-md/screen-ui/back-and-gestures.md +2 -2
- package/docs-md/start/installation.md +3 -1
- package/ios/CLAUDE.md +17 -5
- package/ios/CORE.md +13 -8
- package/ios/Contract/ANNCommandAnswer.mm +5 -20
- package/ios/Contract/ANNCommandContract.h +15 -0
- package/ios/Contract/ANNCommandContract.mm +78 -0
- package/ios/Core/ANNAppearanceDispatcher.mm +1 -1
- package/ios/Core/ANNErrorHandler.h +1 -1
- package/ios/Core/ANNErrorHandler.mm +3 -1
- package/ios/Core/ANNEventEmitter.h +1 -1
- package/ios/Core/ANNEventEmitter.mm +2 -2
- package/ios/Core/ANNJavaScriptCalls.h +34 -0
- package/ios/Core/ANNJavaScriptCalls.mm +61 -0
- package/ios/Core/ANNNavigationState.h +7 -3
- package/ios/Core/ANNNavigationState.mm +10 -5
- package/ios/Core/ANNNodeHelper.h +32 -12
- package/ios/Core/ANNNodeHelper.mm +100 -3
- package/ios/Core/ANNRenderWait.h +15 -1
- package/ios/Core/ANNRenderWait.mm +119 -17
- package/ios/Core/UIViewController+LayoutProtocol.h +9 -2
- package/ios/Core/UIViewController+LayoutProtocol.mm +8 -0
- package/ios/Layouts/Modal/ANNModalCoordinator.h +1 -1
- package/ios/Layouts/Modal/ANNModalCoordinator.mm +55 -14
- package/ios/Layouts/Screen/ANNComponentViewController.h +8 -0
- package/ios/Layouts/Screen/ANNComponentViewController.mm +32 -5
- package/ios/Layouts/Screen/ANNScreenPlace.h +41 -0
- package/ios/Layouts/Screen/ANNScreenPlace.mm +175 -0
- package/ios/Layouts/SplitView/ANNSplitViewCommands.h +3 -2
- package/ios/Layouts/SplitView/ANNSplitViewCommands.mm +105 -39
- package/ios/Layouts/SplitView/ANNSplitViewController.mm +4 -2
- package/ios/Layouts/Stack/ANNStackCommands.mm +1 -0
- package/ios/Layouts/Stack/ANNStackController.mm +26 -3
- package/ios/Layouts/Stack/ANNStackQueue.h +3 -1
- package/ios/Layouts/Stack/ANNStackQueue.mm +56 -43
- package/ios/Layouts/Stack/UINavigationController+ANNCommands.h +4 -2
- package/ios/Layouts/Stack/UINavigationController+ANNCommands.mm +2 -3
- package/ios/Layouts/Tabs/ANNBottomTabItemBuilder.h +4 -0
- package/ios/Layouts/Tabs/ANNBottomTabItemBuilder.mm +11 -0
- package/ios/Layouts/Tabs/ANNBottomTabsController.mm +13 -5
- package/ios/Layouts/Tabs/ANNBottomTabsPresenter.h +2 -2
- package/ios/Layouts/Tabs/ANNBottomTabsPresenter.mm +109 -7
- package/ios/Options/ANNOptionsCache.h +7 -6
- package/ios/Options/ANNSearchBarOptions.h +4 -3
- package/ios/Options/ANNUserChoice.h +57 -0
- package/ios/Options/ANNUserChoice.mm +44 -0
- package/ios/Options/Params/ANNImageSource.h +61 -0
- package/ios/Options/Params/ANNImageSource.mm +101 -0
- package/ios/Options/Params/ANNOptionImages.h +37 -0
- package/ios/Options/Params/ANNOptionImages.mm +284 -0
- package/ios/Options/Params/Image.h +11 -2
- package/ios/Options/Params/Image.mm +15 -2
- package/ios/Options/Params/ImageParser.h +5 -5
- package/ios/Options/Params/ImageParser.mm +28 -46
- package/ios/Public/ApexNavigation/ApexNavigation.h +1 -1
- package/ios/RECIPES.md +11 -5
- package/ios/React/Slots/ANNSlotComponentView.mm +24 -17
- package/ios/React/Slots/ANNSlotContainers.h +14 -6
- package/ios/React/Slots/ANNSlotContainers.mm +75 -2
- package/ios/TopBar/ANNBarButtons.h +9 -5
- package/ios/TopBar/ANNBarButtons.mm +211 -63
- package/ios/TopBar/ANNIconButtonImage.h +1 -0
- package/ios/TopBar/ANNIconButtonImage.mm +34 -1
- package/ios/TopBar/ANNLargeTitlePresenter.h +13 -0
- package/ios/TopBar/ANNLargeTitlePresenter.mm +26 -3
- package/ios/TopBar/ANNSearchPresenter.mm +170 -19
- package/ios/TopBar/ANNTopBarPresenter.h +5 -0
- package/ios/TopBar/ANNTopBarPresenter.mm +60 -11
- package/ios/TurboModules/ANNTurboModule.mm +39 -21
- package/lib/module/ARCHITECTURE.md +18 -18
- package/lib/module/adapters/NativeANNTurboModule.js.map +1 -1
- package/lib/module/api/navigation.js.map +1 -1
- package/lib/module/engine/commands.js +9 -7
- package/lib/module/engine/commands.js.map +1 -1
- package/lib/module/engine/layout.js +13 -9
- package/lib/module/engine/layout.js.map +1 -1
- package/lib/module/engine/options.js +44 -11
- package/lib/module/engine/options.js.map +1 -1
- package/lib/module/engine/places.js +44 -7
- package/lib/module/engine/places.js.map +1 -1
- package/lib/module/engine/props.js +30 -1
- package/lib/module/engine/props.js.map +1 -1
- package/lib/module/engine/rememberedOptions.js +1 -1
- package/lib/module/engine/rememberedOptions.js.map +1 -1
- package/lib/module/engine/screens.js +22 -12
- package/lib/module/engine/screens.js.map +1 -1
- package/lib/module/interfaces/contract/commands.json +101 -0
- package/lib/typescript/adapters/NativeANNTurboModule.d.ts +5 -2
- package/lib/typescript/adapters/NativeANNTurboModule.d.ts.map +1 -1
- package/lib/typescript/api/events/navigationEvents.d.ts +1 -1
- package/lib/typescript/api/events/navigationEvents.d.ts.map +1 -1
- package/lib/typescript/api/hooks/useNavigation.d.ts +1 -1
- package/lib/typescript/api/hooks/useNavigation.d.ts.map +1 -1
- package/lib/typescript/api/navigation.d.ts +4 -1
- package/lib/typescript/api/navigation.d.ts.map +1 -1
- package/lib/typescript/engine/commands.d.ts.map +1 -1
- package/lib/typescript/engine/options.d.ts +5 -2
- package/lib/typescript/engine/options.d.ts.map +1 -1
- package/lib/typescript/engine/places.d.ts +5 -2
- package/lib/typescript/engine/places.d.ts.map +1 -1
- package/lib/typescript/engine/props.d.ts +8 -1
- package/lib/typescript/engine/props.d.ts.map +1 -1
- package/lib/typescript/engine/rememberedOptions.d.ts.map +1 -1
- package/lib/typescript/engine/screens.d.ts.map +1 -1
- package/lib/typescript/interfaces/ComponentEvents.d.ts +2 -2
- package/lib/typescript/interfaces/ComponentEvents.d.ts.map +1 -1
- package/lib/typescript/interfaces/Events.d.ts +19 -10
- package/lib/typescript/interfaces/Events.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/animations.d.ts +5 -2
- package/lib/typescript/interfaces/options/animations.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/buttons.d.ts +13 -5
- package/lib/typescript/interfaces/options/buttons.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/topBar.d.ts +22 -9
- package/lib/typescript/interfaces/options/topBar.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/ARCHITECTURE.md +18 -18
- package/src/adapters/NativeANNTurboModule.ts +5 -2
- package/src/api/events/navigationEvents.ts +1 -1
- package/src/api/hooks/useNavigation.ts +1 -1
- package/src/api/navigation.ts +4 -1
- package/src/engine/commands.ts +19 -7
- package/src/engine/layout.ts +16 -9
- package/src/engine/options.ts +39 -11
- package/src/engine/places.ts +56 -7
- package/src/engine/props.ts +30 -1
- package/src/engine/rememberedOptions.ts +4 -1
- package/src/engine/screens.tsx +23 -13
- package/src/interfaces/ComponentEvents.ts +2 -2
- package/src/interfaces/Events.ts +19 -10
- package/src/interfaces/contract/commands.json +101 -0
- package/src/interfaces/options/animations.ts +5 -2
- package/src/interfaces/options/buttons.ts +13 -5
- package/src/interfaces/options/topBar.ts +22 -9
|
@@ -1,12 +1,26 @@
|
|
|
1
1
|
#import "ANNRenderWait.h"
|
|
2
2
|
#import "ANNAssert.h"
|
|
3
3
|
#import "ANNComponentViewController.h"
|
|
4
|
+
#import "ANNJavaScriptCalls.h"
|
|
4
5
|
#import "ANNScreenReadiness.h"
|
|
5
6
|
#import "UIViewController+LayoutProtocol.h"
|
|
7
|
+
#import <QuartzCore/QuartzCore.h>
|
|
6
8
|
|
|
7
9
|
// A screen whose rendered state stays unknown counts as ready after this, with `unknownContentRule`.
|
|
8
10
|
static const NSTimeInterval ANNUnknownContentLimit = 1;
|
|
9
11
|
|
|
12
|
+
// What a kind of the bar whose limit passed in the content phase still gets, with `barLimitsFromStart`: a limit of 0
|
|
13
|
+
// would mean none of its own.
|
|
14
|
+
static const NSTimeInterval ANNPassedBarLimit = 0.001;
|
|
15
|
+
|
|
16
|
+
// What is left of a bar kind's `limit` after `spent`; no limit of its own stays none.
|
|
17
|
+
static NSTimeInterval ANNBarLimitLeft(NSTimeInterval limit, NSTimeInterval spent) {
|
|
18
|
+
if (limit <= 0) {
|
|
19
|
+
return limit;
|
|
20
|
+
}
|
|
21
|
+
return MAX(limit - spent, ANNPassedBarLimit);
|
|
22
|
+
}
|
|
23
|
+
|
|
10
24
|
// The number of the last wait made: each wait listens under a key of its own.
|
|
11
25
|
static NSUInteger ANNRenderWaitCount;
|
|
12
26
|
|
|
@@ -18,12 +32,18 @@ static NSUInteger ANNRenderWaitCount;
|
|
|
18
32
|
ANNRenderWaitBar _bar;
|
|
19
33
|
ANNBarWaitLimits _barLimits;
|
|
20
34
|
NSString *_key;
|
|
35
|
+
// When the running wait started (`barLimitsFromStart`).
|
|
36
|
+
CFTimeInterval _startTime;
|
|
21
37
|
// The token: each start, phase and end takes the next one, so that what an earlier one set up does nothing.
|
|
22
38
|
NSUInteger _number;
|
|
23
39
|
// Inside `start`: a step runs as it is, under the caller's protection.
|
|
24
40
|
BOOL _starting;
|
|
25
41
|
// Inside `setUp`: a ready handler leaves the node to the readiness test after it.
|
|
26
42
|
BOOL _settingUp;
|
|
43
|
+
// The content is there and the phase waits for the calls JavaScript made by then (`settlesThroughJavaScript`); the
|
|
44
|
+
// number of that settle, so that one of an earlier take does nothing.
|
|
45
|
+
BOOL _settling;
|
|
46
|
+
NSUInteger _settleNumber;
|
|
27
47
|
// The content nodes still waited, and every node the wait set its ready handler on.
|
|
28
48
|
NSHashTable<UIViewController *> *_waited;
|
|
29
49
|
NSHashTable<UIViewController *> *_listened;
|
|
@@ -70,6 +90,7 @@ static NSUInteger ANNRenderWaitCount;
|
|
|
70
90
|
_isWaiting = YES;
|
|
71
91
|
_isInBarPhase = NO;
|
|
72
92
|
_mountLimitPassed = NO;
|
|
93
|
+
_startTime = CACurrentMediaTime();
|
|
73
94
|
NSUInteger number = ++_number;
|
|
74
95
|
_starting = YES;
|
|
75
96
|
@try {
|
|
@@ -117,11 +138,9 @@ static NSUInteger ANNRenderWaitCount;
|
|
|
117
138
|
if (![self runs:number]) {
|
|
118
139
|
return;
|
|
119
140
|
}
|
|
120
|
-
|
|
121
|
-
[_waited removeObject:_node];
|
|
122
|
-
}
|
|
141
|
+
[self testNode];
|
|
123
142
|
if (_waited.count == 0 && !_barWait) {
|
|
124
|
-
[self
|
|
143
|
+
[self contentOfNumber:number];
|
|
125
144
|
}
|
|
126
145
|
}
|
|
127
146
|
|
|
@@ -206,7 +225,7 @@ static NSUInteger ANNRenderWaitCount;
|
|
|
206
225
|
}
|
|
207
226
|
[_waited removeObject:node];
|
|
208
227
|
if (_waited.count == 0 && !_barWait) {
|
|
209
|
-
[self
|
|
228
|
+
[self contentOfNumber:number];
|
|
210
229
|
}
|
|
211
230
|
}
|
|
212
231
|
|
|
@@ -219,6 +238,36 @@ static NSUInteger ANNRenderWaitCount;
|
|
|
219
238
|
if (_waited.count > 0) {
|
|
220
239
|
return;
|
|
221
240
|
}
|
|
241
|
+
[self contentOfNumber:number];
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// What the running phase waited for came by its signals, or was there already. The content phase with
|
|
245
|
+
// `settlesThroughJavaScript` ends once the calls JavaScript made by now are applied: the commit that mounted the content
|
|
246
|
+
// ran its layout effects (`useScreenOptions`) in the same task of the JavaScript thread, so their `mergeOptions` are on
|
|
247
|
+
// their way to the main queue ahead of the settle. Content that was there already (as the wait starts or takes its
|
|
248
|
+
// screens again) may have mounted in a commit that ran just now: it settles too. The bar phase, and screens without
|
|
249
|
+
// React content (a native screen), end at once.
|
|
250
|
+
- (void)contentOfNumber:(NSUInteger)number {
|
|
251
|
+
if (!_settlesThroughJavaScript || _isInBarPhase || ![self hasReactScreen]) {
|
|
252
|
+
[self phaseOfNumber:number endedMarkingReady:NO];
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
if (_settling) {
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
_settling = YES;
|
|
259
|
+
NSUInteger settle = ++_settleNumber;
|
|
260
|
+
__weak ANNRenderWait *weakSelf = self;
|
|
261
|
+
[ANNJavaScriptCalls afterCallsMadeSoFar:^{
|
|
262
|
+
[weakSelf settleOfNumber:number settle:settle];
|
|
263
|
+
}];
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
- (void)settleOfNumber:(NSUInteger)number settle:(NSUInteger)settle {
|
|
267
|
+
if (![self runs:number] || !_settling || settle != _settleNumber) {
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
_settling = NO;
|
|
222
271
|
[self phaseOfNumber:number endedMarkingReady:NO];
|
|
223
272
|
}
|
|
224
273
|
|
|
@@ -240,9 +289,18 @@ static NSUInteger ANNRenderWaitCount;
|
|
|
240
289
|
}
|
|
241
290
|
}
|
|
242
291
|
|
|
243
|
-
// The limit: what is still waited counts as rendered from now on, its held events go at once.
|
|
292
|
+
// The limit: what is still waited counts as rendered from now on, its held events go at once. A phase that only waits
|
|
293
|
+
// for the calls of JavaScript (its content is there) ends without marking anything.
|
|
244
294
|
- (void)limitOfNumber:(NSUInteger)number {
|
|
245
|
-
if (![self runs:number]
|
|
295
|
+
if (![self runs:number]) {
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
if (_settling) {
|
|
299
|
+
[self stopSettling];
|
|
300
|
+
[self phaseOfNumber:number endedMarkingReady:NO];
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
if (_waited.count == 0 && !_barWait) {
|
|
246
304
|
return;
|
|
247
305
|
}
|
|
248
306
|
[self phaseOfNumber:number endedMarkingReady:YES];
|
|
@@ -288,7 +346,7 @@ static NSUInteger ANNRenderWaitCount;
|
|
|
288
346
|
[self markContentReady];
|
|
289
347
|
}
|
|
290
348
|
if (self->_bar == ANNRenderWaitBarAfterContent && !self->_isInBarPhase) {
|
|
291
|
-
[self
|
|
349
|
+
[self startBarPhaseWithLimits:[self barLimitsAfterContent]];
|
|
292
350
|
return;
|
|
293
351
|
}
|
|
294
352
|
[self finish];
|
|
@@ -309,9 +367,10 @@ static NSUInteger ANNRenderWaitCount;
|
|
|
309
367
|
|
|
310
368
|
#pragma mark - The bar phase
|
|
311
369
|
|
|
312
|
-
// The content is there: the bar components of the screens now, each kind to its
|
|
313
|
-
// for ends the wait at once.
|
|
314
|
-
- (void)
|
|
370
|
+
// The content is there: the bar components of the screens now, each kind to its limit in `limits` from now. Nothing to
|
|
371
|
+
// wait for ends the wait at once.
|
|
372
|
+
- (void)startBarPhaseWithLimits:(ANNBarWaitLimits)limits {
|
|
373
|
+
[self stopSettling];
|
|
315
374
|
[_barWait cancel];
|
|
316
375
|
_barWait = nil;
|
|
317
376
|
[self releaseContent];
|
|
@@ -321,7 +380,7 @@ static NSUInteger ANNRenderWaitCount;
|
|
|
321
380
|
NSArray<UIViewController *> *barScreens = [self barScreens];
|
|
322
381
|
[self rememberTakenScreens:barScreens states:nil];
|
|
323
382
|
ANNBarComponentsWait *barWait = [ANNBarComponentsWait waitForScreens:barScreens
|
|
324
|
-
limits:
|
|
383
|
+
limits:limits
|
|
325
384
|
done:^{
|
|
326
385
|
[weakSelf barOfNumber:number];
|
|
327
386
|
}];
|
|
@@ -344,23 +403,28 @@ static NSUInteger ANNRenderWaitCount;
|
|
|
344
403
|
}
|
|
345
404
|
if (_isInBarPhase) {
|
|
346
405
|
[self runStep:^{
|
|
347
|
-
[self
|
|
406
|
+
[self startBarPhaseWithLimits:self->_barLimits];
|
|
348
407
|
}];
|
|
349
408
|
return;
|
|
350
409
|
}
|
|
351
410
|
// The same token: the limit set at the start stays.
|
|
352
411
|
NSUInteger number = _number;
|
|
412
|
+
[self stopSettling];
|
|
353
413
|
[self releaseContent];
|
|
354
414
|
[_barWait cancel];
|
|
355
415
|
_barWait = nil;
|
|
356
|
-
if (take) {
|
|
357
|
-
[self takeScreensOfNumber:number];
|
|
358
|
-
} else {
|
|
416
|
+
if (!take) {
|
|
359
417
|
_takenScreens = nil;
|
|
360
418
|
_takenStates = nil;
|
|
419
|
+
[self phaseOfNumber:number endedMarkingReady:NO];
|
|
420
|
+
return;
|
|
361
421
|
}
|
|
422
|
+
// As at the start: a node ready already counts at once (its ready handler waits for the next time), and content
|
|
423
|
+
// that is there settles again, the settle of the last take having stopped.
|
|
424
|
+
[self takeScreensOfNumber:number];
|
|
425
|
+
[self testNode];
|
|
362
426
|
if (_waited.count == 0 && !_barWait) {
|
|
363
|
-
[self
|
|
427
|
+
[self contentOfNumber:number];
|
|
364
428
|
}
|
|
365
429
|
}
|
|
366
430
|
|
|
@@ -382,6 +446,7 @@ static NSUInteger ANNRenderWaitCount;
|
|
|
382
446
|
|
|
383
447
|
// The wait lets go of everything: its handlers, its bar wait; its limits find another token.
|
|
384
448
|
- (void)stop {
|
|
449
|
+
[self stopSettling];
|
|
385
450
|
_isWaiting = NO;
|
|
386
451
|
_isInBarPhase = NO;
|
|
387
452
|
_takenScreens = nil;
|
|
@@ -404,6 +469,12 @@ static NSUInteger ANNRenderWaitCount;
|
|
|
404
469
|
|
|
405
470
|
#pragma mark - Helpers
|
|
406
471
|
|
|
472
|
+
// A settle on its way does nothing from now on.
|
|
473
|
+
- (void)stopSettling {
|
|
474
|
+
_settling = NO;
|
|
475
|
+
_settleNumber++;
|
|
476
|
+
}
|
|
477
|
+
|
|
407
478
|
// What the content phase's take reads of each screen to decide what it waits for: the readiness it needs, whether it
|
|
408
479
|
// has its content yet, whether that content is ready, and whether its root mounted.
|
|
409
480
|
- (NSArray<NSNumber *> *)takeStateOfScreens:(NSArray<UIViewController *> *)screens {
|
|
@@ -470,6 +541,37 @@ static NSUInteger ANNRenderWaitCount;
|
|
|
470
541
|
return screens;
|
|
471
542
|
}
|
|
472
543
|
|
|
544
|
+
// With `ANNRenderWaitContentNode`, the node counts as ready when every screen of it is.
|
|
545
|
+
- (void)testNode {
|
|
546
|
+
if (_content == ANNRenderWaitContentNode && _node && [self screensAreReady]) {
|
|
547
|
+
[_waited removeObject:_node];
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
// The limits of the bar phase that follows the content phase: with `barLimitsFromStart`, what is left of each since the
|
|
552
|
+
// wait started.
|
|
553
|
+
- (ANNBarWaitLimits)barLimitsAfterContent {
|
|
554
|
+
ANNBarWaitLimits limits = _barLimits;
|
|
555
|
+
if (!_barLimitsFromStart) {
|
|
556
|
+
return limits;
|
|
557
|
+
}
|
|
558
|
+
NSTimeInterval spent = CACurrentMediaTime() - _startTime;
|
|
559
|
+
limits.titleAndBackground = ANNBarLimitLeft(limits.titleAndBackground, spent);
|
|
560
|
+
limits.buttons = ANNBarLimitLeft(limits.buttons, spent);
|
|
561
|
+
return limits;
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
// A screen with React content is among the screens: a commit of React mounted it.
|
|
565
|
+
- (BOOL)hasReactScreen {
|
|
566
|
+
for (UIViewController *node in [self screens]) {
|
|
567
|
+
if ([node isKindOfClass:ANNComponentViewController.class] &&
|
|
568
|
+
((ANNComponentViewController *)node).reactView) {
|
|
569
|
+
return YES;
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
return NO;
|
|
573
|
+
}
|
|
574
|
+
|
|
473
575
|
// Every screen has no content to wait for (a native screen) or its content is ready.
|
|
474
576
|
- (BOOL)screensAreReady {
|
|
475
577
|
for (UIViewController *node in [self screens]) {
|
|
@@ -64,10 +64,17 @@ FOUNDATION_EXPORT ANNWaitedReadiness ANNWaitedReadinessOf(UIViewController *scre
|
|
|
64
64
|
/// The own options merged with `options` (`ANNNodeHelper mergeOwnOptions:`).
|
|
65
65
|
- (void)mergeOwnOptions:(ANNNavigationOptions *)options;
|
|
66
66
|
|
|
67
|
-
/// A change of the own options on a copy (`ANNNodeHelper changeOwnOptions:`): the
|
|
68
|
-
/// choice of the user (a scope, tokens, a checked menu item, a toggled button).
|
|
67
|
+
/// A change of the own options on a copy (`ANNNodeHelper changeOwnOptions:`): what the core keeps of the app's merges.
|
|
69
68
|
- (void)changeOwnOptions:(void (^)(ANNNavigationOptions *options))change;
|
|
70
69
|
|
|
70
|
+
/// A choice of the user in the node's user layer (`ANNNodeHelper setUserChoice:forKey:`): the way a presenter or a
|
|
71
|
+
/// module keeps what the user did (a scope, tokens, a checked menu item, a toggled button, a renamed title). Nil
|
|
72
|
+
/// removes it.
|
|
73
|
+
- (void)setUserChoice:(nullable ANNUserChoice *)choice forKey:(NSString *)key;
|
|
74
|
+
|
|
75
|
+
/// The choice of the user layer under `key`, or nil (`ANNNodeHelper userChoiceForKey:`).
|
|
76
|
+
- (nullable ANNUserChoice *)userChoiceForKey:(NSString *)key;
|
|
77
|
+
|
|
71
78
|
#pragma mark - Readiness
|
|
72
79
|
|
|
73
80
|
/// A ready handler of the node under the waiter's own key (`ANNNodeHelper setReadyHandler:forKey:`): it runs once, the
|
|
@@ -125,6 +125,14 @@ ANNWaitedReadiness ANNWaitedReadinessOf(UIViewController *screen) {
|
|
|
125
125
|
[self.nodeHelper changeOwnOptions:change];
|
|
126
126
|
}
|
|
127
127
|
|
|
128
|
+
- (void)setUserChoice:(ANNUserChoice *)choice forKey:(NSString *)key {
|
|
129
|
+
[self.nodeHelper setUserChoice:choice forKey:key];
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
- (ANNUserChoice *)userChoiceForKey:(NSString *)key {
|
|
133
|
+
return [self.nodeHelper userChoiceForKey:key];
|
|
134
|
+
}
|
|
135
|
+
|
|
128
136
|
#pragma mark - Readiness
|
|
129
137
|
|
|
130
138
|
- (void)setReadyHandler:(dispatch_block_t)handler forKey:(NSString *)key {
|
|
@@ -25,7 +25,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
25
25
|
|
|
26
26
|
/// `dismissModal`: the record of `componentId` (its root's id or any id inside, also of a modal closed below or by the
|
|
27
27
|
/// user), the options merged into its visible screen, the animation from the command's screen, then its state decides.
|
|
28
|
-
/// Answers with the root's id.
|
|
28
|
+
/// Answers with the root's id. The last modal over no root rejects `[ANNErrorTexts modalWithoutRoot:]`, as on Android.
|
|
29
29
|
+ (void)dismissModal:(NSString *)componentId
|
|
30
30
|
options:(nullable NSDictionary *)options
|
|
31
31
|
answer:(ANNCommandAnswer *)answer;
|
|
@@ -277,8 +277,8 @@ static void ANNCollectIds(UIViewController *node, NSMutableSet<NSString *> *ids)
|
|
|
277
277
|
|
|
278
278
|
// The end steps of a record (its show presented, its dismissal ended, closed by the user) run inside UIKit's
|
|
279
279
|
// completions and delegate calls, outside the runner's protection, in any state: a failure there is logged in one line,
|
|
280
|
-
//
|
|
281
|
-
// The gate's `done` ran before the step, as without a failure.
|
|
280
|
+
// answers what of the record still waits for an answer (its show, a chain step, its dismissals:
|
|
281
|
+
// `endFailedOf:showing:exception:`), and its drive stops. The gate's `done` ran before the step, as without a failure.
|
|
282
282
|
+ (void)protectEndOf:(ANNModal *)modal showing:(BOOL)showing step:(dispatch_block_t)step {
|
|
283
283
|
@try {
|
|
284
284
|
step();
|
|
@@ -288,24 +288,43 @@ static void ANNCollectIds(UIViewController *node, NSMutableSet<NSString *> *ids)
|
|
|
288
288
|
: (showing ? @"show a modal" : @"dismiss a modal");
|
|
289
289
|
NSString *reason = exception.reason.length > 0 ? exception.reason : exception.name;
|
|
290
290
|
RCTLogWarn(@"[ApexNavigation] %@", [ANNErrorTexts couldNot:what reason:reason]);
|
|
291
|
-
[self endFailedOf:modal exception:exception];
|
|
291
|
+
[self endFailedOf:modal showing:showing exception:exception];
|
|
292
292
|
}
|
|
293
293
|
}
|
|
294
294
|
|
|
295
|
-
|
|
295
|
+
// A failed end step of `modal`: its show rejects. After a failed show the dismissals that wait for it don't fail with
|
|
296
|
+
// it, as on Android: on a modal that shows they run now and resolve once it went (one still `Presenting` shows: UIKit's
|
|
297
|
+
// completion ran); on one that goes another way (a `dismissAllModals`, with the old root) or went already they resolve
|
|
298
|
+
// with its root's id; on one in another transition (a drag, its own dismissal) they wait for that transition's end.
|
|
299
|
+
// A failed dismissal rejects itself and the dismissals behind it.
|
|
300
|
+
+ (void)endFailedOf:(ANNModal *)modal showing:(BOOL)showing exception:(NSException *)exception {
|
|
296
301
|
if (!modal) {
|
|
297
302
|
return;
|
|
298
303
|
}
|
|
299
304
|
[self stopDriving:modal];
|
|
300
305
|
NSString *show = [NSString stringWithFormat:@"show the screen '%@'", modal.rootId];
|
|
301
|
-
NSString *dismiss = [NSString stringWithFormat:@"dismiss the modal '%@'", modal.rootId];
|
|
302
306
|
[modal.showAnswer reject:[ANNCommandRunner rejectionOf:exception what:show]];
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
307
|
+
ANNModalState state = modal.state;
|
|
308
|
+
BOOL goesAnotherWay = (state == ANNModalStateDismissing && modal.batch) ||
|
|
309
|
+
state == ANNModalStateWithOldRoot ||
|
|
310
|
+
state == ANNModalStateClosedBelow || state == ANNModalStateGone;
|
|
311
|
+
if (showing && state == ANNModalStatePresenting) {
|
|
312
|
+
modal.state = ANNModalStateShown;
|
|
313
|
+
}
|
|
314
|
+
if (showing && modal.state == ANNModalStateShown) {
|
|
315
|
+
[self runPendingOf:modal];
|
|
316
|
+
} else if (showing && goesAnotherWay) {
|
|
317
|
+
[modal.dismissal.answer resolve:modal.rootId];
|
|
318
|
+
[self resolvePendingOf:modal];
|
|
319
|
+
} else if (!showing) {
|
|
320
|
+
NSString *dismiss = [NSString stringWithFormat:@"dismiss the modal '%@'", modal.rootId];
|
|
321
|
+
NSString *dismissText = [ANNCommandRunner rejectionOf:exception what:dismiss];
|
|
322
|
+
[modal.dismissal.answer reject:dismissText];
|
|
323
|
+
NSArray<ANNModalDismissal *> *pending = modal.pending.copy;
|
|
324
|
+
[modal.pending removeAllObjects];
|
|
325
|
+
for (ANNModalDismissal *waiting in pending) {
|
|
326
|
+
[waiting.answer reject:dismissText];
|
|
327
|
+
}
|
|
309
328
|
}
|
|
310
329
|
// A `setRoot` chain goes on (its own steps are guarded by the root coordinator).
|
|
311
330
|
void (^chainStep)(BOOL) = modal.chainStep;
|
|
@@ -333,7 +352,7 @@ static void ANNCollectIds(UIViewController *node, NSMutableSet<NSString *> *ids)
|
|
|
333
352
|
[waiter reject:text];
|
|
334
353
|
}
|
|
335
354
|
for (ANNModal *modal in batch.records.copy) {
|
|
336
|
-
[self endFailedOf:modal exception:exception];
|
|
355
|
+
[self endFailedOf:modal showing:NO exception:exception];
|
|
337
356
|
}
|
|
338
357
|
}
|
|
339
358
|
}
|
|
@@ -537,7 +556,8 @@ static void ANNCollectIds(UIViewController *node, NSMutableSet<NSString *> *ids)
|
|
|
537
556
|
modal.coversUnder = under != nil && under.viewIfLoaded.window == nil;
|
|
538
557
|
NSArray<UIViewController *> *hidden = modal.coversUnder ? @[ under ] : @[];
|
|
539
558
|
@try {
|
|
540
|
-
// The chain step stays on the record until its events went: a failure there tells the chain
|
|
559
|
+
// The chain step stays on the record until its events went: a failure there tells the chain
|
|
560
|
+
// (`endFailedOf:showing:exception:`).
|
|
541
561
|
void (^chainStep)(BOOL) = modal.chainStep;
|
|
542
562
|
if (chainStep) {
|
|
543
563
|
[ANNAppearanceDispatcher endSwitchHiding:hidden showing:@[ root ] events:nil];
|
|
@@ -778,6 +798,11 @@ static void ANNCollectIds(UIViewController *node, NSMutableSet<NSString *> *ids)
|
|
|
778
798
|
[answer reject:[ANNErrorTexts screenNotShown:componentId]];
|
|
779
799
|
return;
|
|
780
800
|
}
|
|
801
|
+
// The last modal over no root (shown before any `setRoot`) stays: nothing would be left to show, as on Android.
|
|
802
|
+
if ([self isLastWithoutRoot:modal]) {
|
|
803
|
+
[answer reject:[ANNErrorTexts modalWithoutRoot:componentId]];
|
|
804
|
+
return;
|
|
805
|
+
}
|
|
781
806
|
// Step 1: the options, read on the main queue; one that can't be read rejects before anything changes. They merge
|
|
782
807
|
// into the modal's visible screen as `mergeOptions` would.
|
|
783
808
|
if (options.count > 0) {
|
|
@@ -815,6 +840,22 @@ static void ANNCollectIds(UIViewController *node, NSMutableSet<NSString *> *ids)
|
|
|
815
840
|
[self dismiss:modal with:dismissal];
|
|
816
841
|
}
|
|
817
842
|
|
|
843
|
+
// No root in the window (the splash, or nothing yet) and no other modal that shows or comes: `modal` is all a dismissal
|
|
844
|
+
// would take away. One closed below, going with the old root or gone takes nothing away, so it doesn't count.
|
|
845
|
+
+ (BOOL)isLastWithoutRoot:(ANNModal *)modal {
|
|
846
|
+
if (modal.state == ANNModalStateClosedBelow || modal.state == ANNModalStateGone ||
|
|
847
|
+
ApexNavigation.mainWindow.rootViewController.isLayoutNode) {
|
|
848
|
+
return NO;
|
|
849
|
+
}
|
|
850
|
+
for (ANNModal *other in ANNModals) {
|
|
851
|
+
if (other != modal && other.state != ANNModalStateClosedBelow &&
|
|
852
|
+
other.state != ANNModalStateWithOldRoot && other.state != ANNModalStateGone) {
|
|
853
|
+
return NO;
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
return YES;
|
|
857
|
+
}
|
|
858
|
+
|
|
818
859
|
// The modal of `node`: the record whose root is the top of `node`'s layout.
|
|
819
860
|
+ (ANNModal *)modalOf:(UIViewController *)node {
|
|
820
861
|
UIViewController *top = node;
|
|
@@ -897,7 +938,7 @@ static void ANNCollectIds(UIViewController *node, NSMutableSet<NSString *> *ids)
|
|
|
897
938
|
[ANNErrorTexts couldNot:what reason:exception.reason ?: exception.name]);
|
|
898
939
|
// The dismissal still open answers, and so do the dismissals waiting behind it (an answer given already
|
|
899
940
|
// stays as it was).
|
|
900
|
-
[self endFailedOf:modal exception:exception];
|
|
941
|
+
[self endFailedOf:modal showing:NO exception:exception];
|
|
901
942
|
done();
|
|
902
943
|
}
|
|
903
944
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#import "ANNArrangementScreenDelegate.h"
|
|
2
2
|
#import "ANNLayoutProtocol.h"
|
|
3
3
|
#import "ANNScreenAppearance.h"
|
|
4
|
+
#import "ANNScreenPlace.h"
|
|
4
5
|
#import "UIViewController+LayoutProtocol.h"
|
|
5
6
|
#import <UIKit/UIKit.h>
|
|
6
7
|
|
|
@@ -42,6 +43,13 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
42
43
|
/// nobody rendered gets its content when UIKit first loads its view.
|
|
43
44
|
- (void)render;
|
|
44
45
|
|
|
46
|
+
/// Where the screen will show while it waits for its content out of it (parked by a stack's or `showInColumn`'s wait,
|
|
47
|
+
/// `ANNParking`): it lays out with that place's safe area and bars (`ANNScreenPlace`), as it will once it shows there.
|
|
48
|
+
/// Asked at each layout, and kept past the parking until UIKit gives the screen a safe area of its own in a parent
|
|
49
|
+
/// (the push lays it out once before that, with none), or as it appears. Nil: its view's own. Set by the one that
|
|
50
|
+
/// parks the screen.
|
|
51
|
+
@property(nonatomic, copy, nullable) ANNScreenPlace *_Nullable (^placeWhileParked)(void);
|
|
52
|
+
|
|
45
53
|
/// Applies the "under bars" rule to the root frame again, then gives the modules the insets, the padding and the
|
|
46
54
|
/// regions of the screen. Nothing before the view loaded; the safe area only in a window.
|
|
47
55
|
- (void)updateRootLayout;
|
|
@@ -162,6 +162,11 @@
|
|
|
162
162
|
[ANNSystemUI setNeedsUpdate];
|
|
163
163
|
[self.arrangement screenDidChangeLayout:self];
|
|
164
164
|
[ANNHinge watchForScreens];
|
|
165
|
+
// A parked screen whose place gave it no safe area at all lays out with its view's own from now on.
|
|
166
|
+
if (self.placeWhileParked && ![ANNParking isUnseen:self]) {
|
|
167
|
+
self.placeWhileParked = nil;
|
|
168
|
+
[self updateRootLayout];
|
|
169
|
+
}
|
|
165
170
|
// Once JavaScript heard the appearance (a driven one ends later, with its command).
|
|
166
171
|
__weak ANNComponentViewController *weakSelf = self;
|
|
167
172
|
[ANNAppearanceDispatcher afterDidAppearOf:self.appearance
|
|
@@ -363,11 +368,31 @@
|
|
|
363
368
|
}
|
|
364
369
|
#endif
|
|
365
370
|
|
|
371
|
+
// The place the screen waits to show in, while it is parked out of it and until UIKit gives it a safe area of its
|
|
372
|
+
// own there: the push lays the screen out once before that, with none, and a list laid out then at the screen's top
|
|
373
|
+
// would stay the list the bar follows. A place that shows with no safe area at all hands over as the screen appears.
|
|
374
|
+
- (nullable ANNScreenPlace *)parkedPlace {
|
|
375
|
+
ANNScreenPlace * (^place)(void) = self.placeWhileParked;
|
|
376
|
+
if (!place) {
|
|
377
|
+
return nil;
|
|
378
|
+
}
|
|
379
|
+
if (![ANNParking isUnseen:self] && self.parentViewController &&
|
|
380
|
+
!UIEdgeInsetsEqualToEdgeInsets(self.view.safeAreaInsets, UIEdgeInsetsZero)) {
|
|
381
|
+
self.placeWhileParked = nil;
|
|
382
|
+
return nil;
|
|
383
|
+
}
|
|
384
|
+
return place();
|
|
385
|
+
}
|
|
386
|
+
|
|
366
387
|
- (CGRect)rootFrameForOptions:(ANNNavigationOptions *)options {
|
|
367
388
|
UIView *view = self.view;
|
|
368
|
-
|
|
369
|
-
BOOL
|
|
370
|
-
|
|
389
|
+
ANNScreenPlace *place = [self parkedPlace];
|
|
390
|
+
BOOL topBarShown = place ? place.showsTopBar : [self hasShownTopBar];
|
|
391
|
+
BOOL tabBarShown = place ? place.showsTabBar : [self hasShownTabBar];
|
|
392
|
+
BOOL fromTop = ANNScreenIsUnderTopBar(options) || !topBarShown;
|
|
393
|
+
BOOL toBottom = ANNScreenIsUnderTabBar(options) || !tabBarShown;
|
|
394
|
+
UIEdgeInsets safeArea = place ? place.safeArea : view.safeAreaInsets;
|
|
395
|
+
return ANNScreenRootFrame(view.bounds, safeArea, fromTop, toBottom);
|
|
371
396
|
}
|
|
372
397
|
|
|
373
398
|
- (void)updateRootLayout {
|
|
@@ -421,8 +446,10 @@
|
|
|
421
446
|
self.nodeHelper.destroyed) {
|
|
422
447
|
return;
|
|
423
448
|
}
|
|
424
|
-
|
|
425
|
-
|
|
449
|
+
// A parked screen has no safe area of its own: it takes its place's.
|
|
450
|
+
ANNScreenPlace *place = [self parkedPlace];
|
|
451
|
+
UIEdgeInsets safeArea = place ? place.safeArea : view.safeAreaInsets;
|
|
452
|
+
UIEdgeInsets insets = ANNScreenInsetsOverRoot(content.frame, view.bounds.size, safeArea);
|
|
426
453
|
UINavigationController *stack = [self shownNavigation];
|
|
427
454
|
ANNScreenPaddingContext context = {
|
|
428
455
|
.inStack = stack != nil,
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
#import "ANNNavigationOptions.h"
|
|
2
|
+
#import <UIKit/UIKit.h>
|
|
3
|
+
|
|
4
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
5
|
+
|
|
6
|
+
/// Where an entry will show on top of a stack, as UIKit lays it out there: the safe area its screens get, and whether
|
|
7
|
+
/// the stack's bar and the tab bar show for it. A screen that waits for its content out of its stack (parked,
|
|
8
|
+
/// `ANNParking`) has no parent view controller, and UIKit gives its view no safe area at all: it lays out with its
|
|
9
|
+
/// place's instead (`placeWhileParked` of `ANNComponentViewController`), so that its root frame, its padding, the
|
|
10
|
+
/// insets JavaScript reads in its first render and its main list are those it has after the push. Nothing of it moves
|
|
11
|
+
/// as the push starts: a list that moved then would lose the large title, which UIKit draws in the list the bar
|
|
12
|
+
/// follows.
|
|
13
|
+
///
|
|
14
|
+
/// The bar's height is UIKit's own: a navigation controller of the core's, unseen in the stack's view for the moment of
|
|
15
|
+
/// the measure, shows an item made like the entry's (title, display mode of the large title, looks, subtitles, prompt,
|
|
16
|
+
/// style, search field) over one like the stack's top, with the stack's bar settings and the entry's toolbar. Main
|
|
17
|
+
/// queue.
|
|
18
|
+
@interface ANNScreenPlace : NSObject
|
|
19
|
+
|
|
20
|
+
- (instancetype)init NS_UNAVAILABLE;
|
|
21
|
+
+ (instancetype)new NS_UNAVAILABLE;
|
|
22
|
+
|
|
23
|
+
/// The place of `entry` (a screen, or a pair whose screens show under its bar) on top of `stack`, with `options` the
|
|
24
|
+
/// resolved options the stack shows its bar and toolbar by; nil when the stack isn't in a window. Measured again only
|
|
25
|
+
/// when something the measure reads changed since the last one for `entry`.
|
|
26
|
+
+ (nullable ANNScreenPlace *)placeOfEntry:(UIViewController *)entry
|
|
27
|
+
inStack:(UINavigationController *)stack
|
|
28
|
+
options:(ANNNavigationOptions *)options;
|
|
29
|
+
|
|
30
|
+
/// The safe area of the entry's view in the place.
|
|
31
|
+
@property(nonatomic, readonly) UIEdgeInsets safeArea;
|
|
32
|
+
|
|
33
|
+
/// The stack's bar shows for the entry (`topBar.visible`).
|
|
34
|
+
@property(nonatomic, readonly) BOOL showsTopBar;
|
|
35
|
+
|
|
36
|
+
/// A tab bar shows at the bottom for the entry: one shows now and the entry doesn't hide it.
|
|
37
|
+
@property(nonatomic, readonly) BOOL showsTabBar;
|
|
38
|
+
|
|
39
|
+
@end
|
|
40
|
+
|
|
41
|
+
NS_ASSUME_NONNULL_END
|