使用 @Published 监听属性的变动
我们已经引入了 UIColorHexSwift 库,这样我们就可以将 CCCCCC 十六进制很方便的转换为 UIColor的对象。
swift
class AppColor: ObservableObject {
@Published var c_cccccc:UIColor = UIColor("#CCCCCC")
}
我们新建了一个颜色变量 c_cccccc = UIColor("#CCCCCC"),而且我们还有一个叫做 @Published的关键词。
@Published 是 SwiftUI 属性包装器是我们可以让 SwiftUI 可以自动监听 @Published 对应属性值的变化,从而更新试图。
@Published 和 @State 区别在于,@State只能在对应 View 的结构体中生命,作用域为 final。但是 @Published 可以让其他的试图共用,并且可以让 SwiftUI 实现 MVVM 的设计模式。
使用 @ObservedObject 引用监听存在的对象
@ObservedObject 这个可以让其他的试图引用已经存在的 ObservableObject 对象,从而公用一个对象的 @Published 属性。
但是我们不可能每个试图都要传递对象进去,这样写程序也太麻烦了。SwiftUI 有没有类似 Flutter Provider 的东西,在顶层依赖之后,后续就可以通过 Context.read() 读取出来进行使用了。
使用 @EnvironmentObject 和 @Environment 设置全局监听
这个还真的存在,那就是 @EnvironmentObject 。还有一个 @Environment,它和 @EnvironmentObject 区别在于,前者在于 SwiftUI 自带系统级别的基本类型,也可以用户扩展。后者是托管全局的 ObservableObject 对象。
⚠️值得注意是使用 @EnvironmentObject 一定保证用之前,在之前试图注册,不然会引起崩溃。
我们将 AppColor 注入到我们的根试图,代码更改如下。
swift
@main
struct Win_App: App {
/// App 的配色
@StateObject var appColor:AppColor = AppColor()
var body: some Scene {
WindowGroup {
LoginPage()
.environmentObject(appColor)
}
}
}
使用 @EnvironmentObject 获取全局监听对象
接下来我们在 LoginValueContentView.swift 页面使用,使用@EnvironmentObject即可。
swift
struct LoginValueContentView: View {
@EnvironmentObject private var appColor:AppColor
var body: some View {
VStack(spacing: 8.0) {
HStack(spacing: 15) {
Image("server_icon")
Text("请选择服务器请选择服务器请选择服务器请选择服务器")
.frame(maxWidth:.infinity,
alignment: .leading)
.lineLimit(1)
.foregroundColor(Color(uiColor: appColor.c_ffcccccc))
Image("drop_icon")
}
Rectangle()
.frame(height:0.5)
.foregroundColor(Color(uiColor: appColor.c_cccccc))
}
}
}
修复 Preview Device 预览错误

我们的预览失败了,但是一点都不慌,因为错误提示已经提示出来了。我们的预览试图没有设置 AppColor 的 Environment Object,想一下也是,刚才我们只是设置给程序入口设置了,但是预览没有设置。

此时预览一切正常,而且我们的组件已经看起来十分的完美。