Skip to content

Instantly share code, notes, and snippets.

@khanlou
Created March 27, 2023 18:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save khanlou/f51e92d36f91972d7ea8a652c237e701 to your computer and use it in GitHub Desktop.
Save khanlou/f51e92d36f91972d7ea8a652c237e701 to your computer and use it in GitHub Desktop.
//
// ContentView.swift
// DependentEnvironment
//
// Created by Soroush Khanlou on 3/27/23.
//
import SwiftUI
struct Inner: View {
@EnvironmentObject var a: OOA
@EnvironmentObject var b: OOB
var body: some View {
Text("Hello, world!")
.onAppear {
a.sayHi()
b.sayHiFromA()
}
}
}
struct ContentView: View {
var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundColor(.accentColor)
Inner()
}
.environmentObject(dependency: OOA.self, { OOB(ooa: $0) })
.environmentObject(OOA())
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
final class OOA: ObservableObject {
func sayHi() {
print("hi from a")
}
}
final class OOB: ObservableObject {
let ooa: OOA
init(ooa: OOA) {
self.ooa = ooa
}
func sayHiFromA() {
ooa.sayHi()
}
}
struct DependentEnvironmentModifier<Dependency: ObservableObject, Output: ObservableObject>: ViewModifier {
let constructor: (Dependency) -> Output
@EnvironmentObject var dependency: Dependency
func body(content: Content) -> some View {
content
.environmentObject(constructor(dependency))
}
}
extension View {
func environmentObject<D: ObservableObject, O: ObservableObject>(dependency: D.Type, _ constructor: @escaping (D) -> O) -> some View {
self.modifier(DependentEnvironmentModifier<D, O>(constructor: constructor))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment