为什么 ViewModifier 不使用 EnvironmentKey 应用更改?

问题描述 投票:0回答:1

我有这个测试代码,我认为我的代码一切正确,但由于某些原因它不起作用,我的意思是它不应用修改。我看不到问题,为什么?

import SwiftUI

struct ContentView: View {
    var body: some View {
        MyView(value: "Hello, world!", color: .red, border: true)
            .bordered()
    }
}

struct MyView: View {
    
    let value: String
    let color: Color
    let border: Bool
    
    var body: some View {
        Text(value)
            .foregroundStyle(color)
            .environment(\.borderColor, color)
            .environment(\.isBorderEnabled, border)

    }
}

struct BorderedModifier: ViewModifier {
    
    @Environment(\.borderColor) private var color
    @Environment(\.isBorderEnabled) private var border
    
    func body(content: Content) -> some View {
        Group {
            if (border) {
                content
                    .padding(5.0)
                    .overlay(
                        RoundedRectangle(cornerRadius: 4)
                            .stroke(color, lineWidth: 2)
                    )
            } else {
                content
            }
        }
    }
}

extension View {
    func bordered() -> some View {
        self.modifier(BorderedModifier())
    }
}


private struct BorderColorKey: EnvironmentKey {
    static let defaultValue: Color = .black
}

private struct BorderEnabledKey: EnvironmentKey {
    static let defaultValue: Bool = false
}

extension EnvironmentValues {
    var borderColor: Color {
        get { self[BorderColorKey.self] }
        set { self[BorderColorKey.self] = newValue }
    }
    
    var isBorderEnabled: Bool {
        get { self[BorderEnabledKey.self] }
        set { self[BorderEnabledKey.self] = newValue }
    }
}
swift swiftui
1个回答
0
投票

当您更改

@Enviroment
的值时,新值仅适用于子视图。因此
MyView
的子视图将具有
isBorderEnabled = true
但在 MyView 本身中
isBorderEnabled
仍然是
false
。我已经根据您的代码创建了一个示例来演示您可以更改:

@main
struct SwiftUITestApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
                .environment(\.isBorderEnabled, true)
        }
    }
}

struct ContentView: View {
    var body: some View {
        VStack {
            MyView(value: "Hello, world!", color: .red, border: false)
                .padding(8)
                .bordered()
        }
    }
}

struct MyView: View {
    
    let value: String
    let color: Color
    let border: Bool
    
    var body: some View {
        ChildMyView()
            .foregroundStyle(color)
            .environment(\.borderColor, color)
            .environment(\.isBorderEnabled, border)
    }
}

struct ChildMyView: View {
    @Environment(\.isBorderEnabled) private var border
    
    var body: some View {
        Text("HELLO WORLD")
            .bordered()
    }
}

struct BorderedModifier: ViewModifier {
    
    @Environment(\.borderColor) private var color
    @Environment(\.isBorderEnabled) private var border
    
    func body(content: Content) -> some View {
        Group {
            let _ = print(border)
            if (border) {
                content
                    .padding(5.0)
                    .overlay(
                        RoundedRectangle(cornerRadius: 4)
                            .stroke(color, lineWidth: 2)
                    )
            } else {
                content
            }
        }
    }
}

extension View {
    func bordered() -> some View {
        self.modifier(BorderedModifier())
    }
}


private struct BorderColorKey: EnvironmentKey {
    static let defaultValue: Color = .black
}

private struct BorderEnabledKey: EnvironmentKey {
    static let defaultValue: Bool = false
}

extension EnvironmentValues {
    var borderColor: Color {
        get { self[BorderColorKey.self] }
        set { self[BorderColorKey.self] = newValue }
    }
    
    var isBorderEnabled: Bool {
        get { self[BorderEnabledKey.self] }
        set { self[BorderEnabledKey.self] = newValue }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.