【问题标题】:How to set a custom environment key in SwiftUI?如何在 SwiftUI 中设置自定义环境键?
【发布时间】:2020-05-17 04:37:49
【问题描述】:

创建自定义环境键是可行的,但如果我想在视图中设置值,XCODE 不允许这样做。但是可以设置预定义的环境值。我做错了什么?

struct ResetDefault: EnvironmentKey {
    static var defaultValue: Bool = false
}

extension EnvironmentValues {
    var resetDefault: Bool {
        get { self[ResetDefault.self] }
        set { self[ResetDefault.self] = newValue }
    }
}

struct ResetView: View {
    @Environment(\.resetDefault) var reset
    var body: some View {
        Text("Reset").onAppear() {
            reset = true.        // Cannot assign to property: 'reset' is a get-only property
        }
    }
}

【问题讨论】:

    标签: swiftui


    【解决方案1】:

    Environment 用于在parent > child 方向传递值,因此设置了值以供使用。如果您想更改环境值的internal,那么您需要以某种方式包装它,可能的变体是绑定或引用类型持有者。

    这是一个基于绑定的使用示例(类似于 .editMode 和 .presentationMode 的工作方式)

    struct TestResetEnv: View {
        @State private var isActive = false
        @State private var reset = false
        var body: some View {
            VStack {
                Text("Current: \(reset ? "true" : "false")")
                Button("Go") { self.isActive.toggle() }
                if isActive {
                    ResetView()
                }
            }.environment(\.resetDefault, $reset) // set for children as env!!
        }
    }
    
    struct ResetDefault: EnvironmentKey {
        static var defaultValue: Binding<Bool> = .constant(false)
    }
    
    extension EnvironmentValues {
        var resetDefault: Binding<Bool> {
            get { self[ResetDefault.self] }
            set { self[ResetDefault.self] = newValue }
        }
    }
    
    struct ResetView: View {
        @Environment(\.resetDefault) var reset
        var body: some View {
            Text("Reset").onAppear() {
                self.reset.wrappedValue.toggle() // << change wrapped !!
            }
        }
    }
    

    【讨论】:

    • 你能想出一个实际使用这种可编辑环境值的例子吗?我想知道这是否不应该几乎总是 EnvironmentObject 上的属性...
    • @RalfEbert,使用这种方法的现实解决方案SwiftUI - How to close the sheet view, while dismissing that view
    • @RalfEbert,另一个使用引用类型SwiftUI how to change state on keyUp macOS event?
    • 此解决方案可以编译但不起作用。包装的值永远不会与默认值有任何不同。
    • 其实更正:很好的解决方案,你要记得添加: .environment(\.resetDefault, $reset) (否则没有警告或错误,但没有任何反应)
    猜你喜欢
    • 1970-01-01
    • 2022-12-02
    • 1970-01-01
    • 2018-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多