1
1
@preconcurrency import ComposableArchitecture
2
2
import SwiftUI
3
+ import SwiftUINavigation
3
4
4
5
private struct PresentationTestCase : Reducer {
5
6
struct State : Equatable {
@@ -8,6 +9,7 @@ private struct PresentationTestCase: Reducer {
8
9
}
9
10
enum Action : Equatable , Sendable {
10
11
case alertButtonTapped
12
+ case customAlertButtonTapped
11
13
case destination( PresentationAction < Destination . Action > )
12
14
case dialogButtonTapped
13
15
case fullScreenCoverButtonTapped
@@ -20,6 +22,7 @@ private struct PresentationTestCase: Reducer {
20
22
struct Destination : Reducer {
21
23
enum State : Equatable {
22
24
case alert( AlertState < AlertAction > )
25
+ case customAlert
23
26
case dialog( ConfirmationDialogState < DialogAction > )
24
27
case fullScreenCover( ChildFeature . State )
25
28
case navigationDestination( ChildFeature . State )
@@ -29,6 +32,7 @@ private struct PresentationTestCase: Reducer {
29
32
}
30
33
enum Action : Equatable {
31
34
case alert( AlertAction )
35
+ case customAlert( AlertAction )
32
36
case dialog( DialogAction )
33
37
case fullScreenCover( ChildFeature . Action )
34
38
case navigationDestination( ChildFeature . Action )
@@ -96,6 +100,9 @@ private struct PresentationTestCase: Reducer {
96
100
}
97
101
)
98
102
return . none
103
+ case . customAlertButtonTapped:
104
+ state. destination = . customAlert
105
+ return . none
99
106
case . destination( . presented( . fullScreenCover( . parentSendDismissActionButtonTapped) ) ) ,
100
107
. destination( . presented( . sheet( . parentSendDismissActionButtonTapped) ) ) ,
101
108
. destination( . presented( . popover( . parentSendDismissActionButtonTapped) ) ) :
@@ -225,23 +232,26 @@ private struct ChildFeature: Reducer {
225
232
226
233
struct PresentationTestCaseView : View {
227
234
private let store : StoreOf < PresentationTestCase >
228
- @StateObject private var viewStore : ViewStore < String , PresentationTestCase . Action >
235
+ @StateObject private var viewStore : ViewStore < PresentationTestCase . State , PresentationTestCase . Action >
236
+ @State var alertMessage = " "
229
237
230
238
init ( ) {
231
239
let store = Store (
232
240
initialState: PresentationTestCase . State ( ) ,
233
- reducer: PresentationTestCase ( ) . _printChanges ( )
241
+ reducer: PresentationTestCase ( )
242
+ . _printChanges ( )
234
243
)
235
244
self . store = store
236
245
self . _viewStore = StateObject (
237
- wrappedValue: ViewStore ( store, observe: { $0. message } )
246
+ wrappedValue: ViewStore ( store, observe: { $0 } )
238
247
)
239
248
}
240
249
241
250
var body : some View {
242
251
Form {
243
252
Section {
244
- Text ( self . viewStore. state)
253
+ Text ( self . viewStore. message)
254
+ Text ( self . alertMessage)
245
255
}
246
256
247
257
Button ( " Open alert " ) {
@@ -254,6 +264,21 @@ struct PresentationTestCaseView: View {
254
264
action: PresentationTestCase . Destination. Action. alert
255
265
)
256
266
267
+ Button ( " Open custom alert " ) {
268
+ self . viewStore. send ( . customAlertButtonTapped)
269
+ }
270
+ . alert (
271
+ " Custom alert! " ,
272
+ isPresented: viewStore
273
+ . binding ( get: \. destination, send: PresentationTestCase . Action. destination ( . dismiss) )
274
+ . case ( / PresentationTestCase. Destination. State. customAlert)
275
+ . isPresent ( )
276
+ ) {
277
+ TextField ( " Message " , text: self . $alertMessage)
278
+ Button ( " Submit " ) { }
279
+ Button ( " Cancel " , role: . cancel) { }
280
+ }
281
+
257
282
Button ( " Open dialog " ) {
258
283
self . viewStore. send ( . dialogButtonTapped)
259
284
}
@@ -370,10 +395,14 @@ private struct NavigationLinkDemoFeature: ReducerProtocol {
370
395
struct State : Equatable {
371
396
var message = " "
372
397
@PresentationState var child : ChildFeature . State ?
398
+ @PresentationState var identifiedChild : ChildFeature . State ?
373
399
}
374
400
enum Action : Equatable {
375
401
case child( PresentationAction < ChildFeature . Action > )
402
+ case identifiedChild( PresentationAction < ChildFeature . Action > )
403
+ case identifiedNavigationLinkButtonTapped
376
404
case navigationLinkButtonTapped
405
+ case nonDeadbeefIdentifiedNavigationLinkButtonTapped
377
406
}
378
407
var body : some ReducerProtocolOf < Self > {
379
408
Reduce < State , Action > { state, action in
@@ -390,16 +419,30 @@ private struct NavigationLinkDemoFeature: ReducerProtocol {
390
419
case . child( . presented( . parentSendDismissActionButtonTapped) ) :
391
420
state. child = nil
392
421
return . none
393
- case . child:
422
+ case . identifiedChild( . presented( . parentSendDismissActionButtonTapped) ) :
423
+ state. child = nil
424
+ return . none
425
+ case . child, . identifiedChild:
426
+ return . none
427
+ case . identifiedNavigationLinkButtonTapped:
428
+ state. identifiedChild = ChildFeature . State (
429
+ id: UUID ( uuidString: " deadbeef-dead-beef-dead-beefdeadbeef " ) !
430
+ )
394
431
return . none
395
432
case . navigationLinkButtonTapped:
396
433
state. child = ChildFeature . State ( )
397
434
return . none
435
+ case . nonDeadbeefIdentifiedNavigationLinkButtonTapped:
436
+ state. identifiedChild = ChildFeature . State ( )
437
+ return . none
398
438
}
399
439
}
400
440
. ifLet ( \. $child, action: / Action. child) {
401
441
ChildFeature ( )
402
442
}
443
+ . ifLet ( \. $identifiedChild, action: / Action. identifiedChild) {
444
+ ChildFeature ( )
445
+ }
403
446
}
404
447
}
405
448
@@ -411,16 +454,34 @@ private struct NavigationLinkDemoView: View {
411
454
Form {
412
455
WithViewStore ( self . store, observe: \. message) { viewStore in
413
456
Text ( viewStore. state)
414
-
457
+
415
458
NavigationLinkStore (
416
- store : self . store. scope ( state: \. $child, action: NavigationLinkDemoFeature . Action. child)
459
+ self . store. scope ( state: \. $child, action: NavigationLinkDemoFeature . Action. child)
417
460
) {
418
461
viewStore. send ( . navigationLinkButtonTapped)
419
462
} destination: { store in
420
463
ChildView ( store: store)
421
464
} label: {
422
465
Text ( " Open navigation link " )
423
466
}
467
+
468
+ NavigationLinkStore (
469
+ self . store. scope (
470
+ state: \. $identifiedChild,
471
+ action: NavigationLinkDemoFeature . Action. identifiedChild
472
+ ) ,
473
+ id: UUID ( uuidString: " deadbeef-dead-beef-dead-beefdeadbeef " ) !
474
+ ) {
475
+ viewStore. send ( . identifiedNavigationLinkButtonTapped)
476
+ } destination: { store in
477
+ ChildView ( store: store)
478
+ } label: {
479
+ Text ( " Open identified navigation link " )
480
+ }
481
+
482
+ Button ( " Open non-deadbeef identified navigation link " ) {
483
+ viewStore. send ( . nonDeadbeefIdentifiedNavigationLinkButtonTapped)
484
+ }
424
485
}
425
486
}
426
487
}
0 commit comments