Tricky. I can think of a few things.
If the acknowledgement of completion/cancellation is essential to View2
. The handling needs to be passed into the init
functions. Returning a not-yet-working type isn't great, doubly more so in a declarative structure like SwiftUI.
You could pass in closures:
struct View2: View {
init(onComplete: () -> () = { }, onCancel: () -> () = {}) { ... }
}
You could pass in publishers:
struct View2<CompletionPublisher, CancellationPublisher>: View {
init(completionPublisher: CompletionPublisher, cancellationPublisher: CancellationPublisher) { ... }
}
You can type-erase if you need to. Personally I'd minimize type-erasure as much as possible.
Or it could be a hidden ObservableObject
all along:
class ViewState: ObservableObject {
func complete() { ... }
func cancel() { ... }
}
struct View2 {
init(viewState: ViewState) { ... }
}
If the handling is not essential, we could do a few tricks:
We could add:
struct View2 {
var completeSubject: ..., cancelSubject: ...
func handle(onComplete: () -> (), onCancel: () -> ()) -> some View {
self
.onReceive(completeSubject, perform: onComplete)
.onReceive(cancelSubject, perform: onCancel)
}
}
We could use UserPreferenceKey
:
struct View2StatePreferenceKey: PreferenceKey {
enum Value {
case active, completed, cancelled
}
static var defaultValue = Value.active
static func reduce(value: inout Value, nextValue: () -> Value) {
value = nextValue()
}
}
struct View2: View {
@State var state = View2StatePreferenceKey.Value.active
var body: some View {
...
.preference(View2StatePreferenceKey.self, value: state)
}
}
struct View1: View {
var body: some View {
...
.onPreferenceChange(View2StatePreferenceKey.self) { newValue in
...
}
}
}
A few more sidenote:
- You don't need to type-erase
completionSubject
to completionPublisher
in your original code. onReceive
takes a generic Publisher
, so completionSubject
will work just fine.
- Personally, I don't like a structure that put
View
into variables. It can be hard to reason with, especially that View
don't have any sense of identity outside of the view hierarchy.