iOS开发SwiftUI

SwiftUI Environment

Environment 是 SwiftUI 中一个独特的功能,使用它可以提供系统范围内的设置如 LayoutDirection,ColorScheme,也可以提供特定于某些 View 的设置如 isEnabled, editMode,presentationMode 等。

在SwiftUI中创建并启动您的第一个View时,框架会为其生成Environment。 Environment是SwiftUI自动创建的,我们不需要做任何事情。 通过Environment可以取得和改变系统环境变量的设置。


通过 @Environment 属性包装可以获取 Environment 的值。
struct ContentView: View {

    // 通过Environment获取系统设定colorScheme的值
    @Environment(\.colorScheme) var colorScheme
    
    var body: some View {
        Group {
            // 根据系统colorScheme的值改变SwiftUI的布局
            if colorScheme == .dark {
                VStack {
                    Text("Hello")
                    Text("SwiftUI")

                } }
            else {
                HStack {
                    Text("Hello")
                    Text("SwiftUI")
                }
            } }
    }

}

可以设定 Environment 的值。
import SwiftUI

struct ContentView: View {
    @State private var fruits = ["Apple", "Banana", "Mango"]
    @State private var isEditable = false

    var body: some View {
        List {
            ForEach(fruits, id: \.self) { user in
                Text(user)
            }
                .onMove(perform: move)
                .onLongPressGesture {
                    withAnimation {
                        self.isEditable = true
                    }
            }
        }
       // 这里改变了 environment editMode的值,从而切换List的编辑模式和普通模式。
        .environment(\.editMode, isEditable ? .constant(.active) : .constant(.inactive))
    }

    func move(from source: IndexSet, to destination: Int) {
        fruits.move(fromOffsets: source, toOffset: destination)
        withAnimation {
            isEditable = false
        }
    }
}

除了用系统的Key,environment也可以自定义EnvironmentKey, 
然后将所需要的设置放到 EnvironmentValues 中提供给外界使用。
  • 遵守 EnvironmentKey 协议,提供默认值。
Struct ColorKey: EnvironmentKey {
    static var defaultValue: Color = .red
}
  • 扩展 EnvironmentValues ,提供计算属性,该属性就是使用@Environment 时的参数Key Path。
extension EnvironmentValues {
// 计算属性类型,和ColorKey中defaultValue类型一致。
    var customColor: Color { 
        get { self[ColorKey.self] }
        set { self[ColorKey.self] = newValue }
    }
}
  • 设置customColor的值。
 ContentView().environment(\.customColor, .blue)
  • 使用自定义的customColor
struct ContentView: View {
    // \.customColor 是前面设置的计算属性
    @Environment(\.customColor) var customColor
    var body: some View {
        HStack {
            Text("Hello")
            Text("SwiftUI")
        }
            .foregroundColor(customColor) // 使用 customColor }
    }
}