SwiftUI状态管理--Combine(Environment

2021-11-29  本文已影响0人  Mehmet

SwiftUI 已经如同前端vue、react 一般支持响应式编程。也有类似前端的 state。如今swiftUI已经到2.0版本。swift 也已经5.5了 。所以现阶段从OC 切换到swift是一个非常合适的时机(有点晚)。了解swift 或者前端就会明白OC的笨重。作为一个已经使用了8年OC的开发来说,切换到swift无疑有着不舍。不过学习新的东西,总是充满了挑战。

通过最近的学习和使用特此整理。本文以实际使用出发。具体实现原理待后面研究源码再进行整理。
在实际项目中使用到的有:


Environment

值类型,当创建应用时,会自动创建Environment。其主要作用是传递系统的一些设置。如ColorScheme、NSManagedObjectContext。系统又很多对应的key可以查看EnvironmentValues获取key列表。
在需要使用的view中,只需要使用PropertyWrapper属性包装器 @Enviroment

import SwiftUI

struct HomePageView: View {
    // colorScheme values: .light, .dark
    @Enviroment(\.colorScheme) var colorScheme
    
    var body: some View {
        Text("Hello, World")
            .foregroundColor(colorScheme = .light ? .yellow : .blue)
    }
}

虽然系统自动创建,不过我们也可以自定义一个EnviromentKey,代码如下:

import Foundation
import SwiftUI

struct UserInfo {
    var userName: String = ""
    init(userName: String) {
        self.userName = userName
    }
}

struct UserInfoKey: EnvironmentKey {
    static var defaultValue: UserInfo {
        return UserInfo(userName: "lixxx")
    }
}

extension EnvironmentValues {
    var userInfo: UserInfo {
        get { return self[UserInfoKey.self] }
        set { self[UserInfoKey] = newValue }
    }
}

在使用自定义的Environment时,要手动去注入到根视图上。并初始化注入对象为其设置一个值。

import SwiftUI

struct ContentView: View {
    
    var body: some View {
        TabbarPageView()
            .environment(\.userInfo, UserInfo(userName: "liqingyu"))
  
    }
}

EnvironmentObject

引用类型,和Environment作用相同,可操作性强,可以使用其为应用进行设置全局变量。共享数据于应用各个页面。
首先创建一个全局对象。因为我们要使用这个对象,并且可能会进行修改,修改后可能会刷新界面等操作。所以我们要观察这个对象 所以使用ObservableObject 协议 通过@Published 当值发生变化时通知全局作出响应。

import Foundation

class Person:ObservableObject {
    @Published var name = ""
}

在根视图上进行注入,子视图将可以进行响应

import SwiftUI

struct ContentView: View {
    
    var body: some View {
        TabbarPageView()
            .environmentObject(Person())  
    }
}

在需要使用的试图进行引入操作

import SwiftUI

struct EnvironmentPageView: View {
    @EnvironmentObject var person: Person
    var body: some View {
        VStack{
            Text("name: \(person.name)")
        }
    }
}

编辑操作,Binding值绑定 及 = 属性设置都是可以的

import SwiftUI

struct EnvironmentDetailView: View {
    @EnvironmentObject var person: Person
    var body: some View {
        TextField("Person", text: $person.name)
            .padding(20)
        .navigationBarTitleDisplayMode(.inline)
         .onAppear(){
                person.name = "liqngyu"
            }
    }
}
上一篇下一篇

猜你喜欢

热点阅读