Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom environment values not honored #1

Open
cyrillelegrand opened this issue Jun 25, 2024 · 1 comment
Open

Custom environment values not honored #1

cyrillelegrand opened this issue Jun 25, 2024 · 1 comment

Comments

@cyrillelegrand
Copy link

Hi!
I need to pass down custom environment values to my variadic children. I've noticed that this is impossible, see a minimal reproduction below:

import SwiftUI
import VariadicViews

struct TestKey: EnvironmentKey {
    static var defaultValue: Int = 0
}

extension EnvironmentValues {
    var testValue: Int {
        get { self[TestKey.self] }
        set { self[TestKey.self] = newValue }
    }
}

struct VariadicThing<Content: View>: View {
    @ViewBuilder let content: Content
    
    var body: some View {
        MultiVariadicView(content) { children in
            ForEach(children) { child in
                child
                    .environment(\.testValue, 42) // my custom environment value is not honored
                    .environment(\.colorScheme, .dark) // but any system-provided env. value is honored!
            }
        }
    }
}

struct Tester: View {
    let name: String
    @Environment(\.testValue) var testValue
    
    var body: some View {
        Text("\(name) = \(testValue)").background(Color(uiColor: .systemBackground))
    }
}

#Preview {
    VStack {
        VariadicThing {
            Tester(name: "Test 1")
            Tester(name: "Test 2")
        }
        Text("All should be = 42").foregroundStyle(.secondary)
    }
    .environment(\.colorScheme, .light)
}

Here is the result:
Screenshot 2024-06-26 at 00 32 42

It should read Test1 = 42 and Test2 = 42. The system-provided environment (\.colorScheme) is correctly passed down to each child, but not my custom environment value.

It works if I do

MultiVariadicView(content.environment(\.testValue, 42)) { children in ... }

but that's not what I want: in my actual project, the values can differ for each child, so I need it inside the ForEach.

Is this a limitation from using a private-ish API like _VariadicView ?

I know this library might very well not be maintained for much longer because iOS 18 offers this natively, but my project targets iOS 16.

@cyrillelegrand
Copy link
Author

After further research, the problem also arises with the new Group(subviewsOf:transform:) in iOS 18 (which coincidentally has the same API than this package).

This indeed seems like a bug in SwiftUI. I've filed a radar under #FB14070467 which you can feel free to duplicate.

Here's the attached demo project I sent to Apple. It both exhibits the problem with the new iOS 18 API, and with this package. As-is, it needs Xcode 16 to compile, but it also runs on Xcode 15 and iOS 16 when commenting out the few lines related to the new API.

variadic_test.zip

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant