
@是属性包装器,通过一个指示器来实现复杂的后台代码,这是非常先进的。
我们已经熟悉@State,用来把界面元素和数据关联起来,由框架自动实现界面和数据的联动。在其他语言中类似功能可能被称为“绑定”,而在SwiftUI里@Binding则表示关联的外部数据。
符号$用来生成变量的绑定,实现双向数据交互。
目录
@State 内部数据绑定
@Binding 关联外部数据
@EnvironmentObject 全局变量
@AppStorage 自动持久化
@EnvironmentObject 究竟是什么
完整示例
@State 内部数据绑定
在视图内定义,其他视图不可直接访问。
@Binding 关联外部数据
在视图内声明,由外部传入,必须是变量,必须是双向绑定(必须加$)。大致代码如下:
struct SwiftUIViewEnv: View {
@Binding var info : String
var body: some View {
Text(info)
}
}
//调用者
@State var bindingstr = "bindingstr"
SwiftUIViewEnv(info:$bindingstr)
//预览
#Preview {
var info = "abc"
SwiftUIViewEnv(info: Binding.constant(info))
}
注意预览那里代码怪怪的。比MAUI强,咱就不说啥了。
@EnvironmentObject 全局变量
环境对象就是全局变量。全局变量必须是ObservableObject,每个需要动态通知的对象需要用@Published包装,大致如此:
class EnvModel: ObservableObject{
@Published var info = "env"
}
每个使用者都需要声明环境变量:
@EnvironmentObject var env: EnvModel
声明之后可以和普通对象一样访问:
Text(env.info)
.onTapGesture {
env.info += "1"
}
预览也需要提前准备一下:
#Preview {
SwiftUIViewEnv().environmentObject(EnvModel())
}
在两个不同的视图访问(敲三下从“env”变成“env111”):
导航到另外一个视图:
说明确实是同一个数据。
实体机运行需要在app入口处准备一下,不然起来就挂了:
//AaaApp.swift
import SwiftUI
@main
struct AaaApp: App {
var body: some Scene {
WindowGroup {
MainView().environmentObject(EnvModel())
}
}
}
@AppStorage 自动持久化
@AppStorage 表明这个变量不仅是@Published,而且自动存储:
class EnvModel: ObservableObject{
@Published var info = "env"
@AppStorage("setting") var setting = "setting"
}
也就是个方便的存储简单配置的方法。
@EnvironmentObject 究竟是什么
通过@EnvironmentObject对同一种模型构造两个不同名字的对象实例行不行?不行!考虑一下之前预览和应用入口的处理,和变量名无关,因此变量名仅仅是方便写代码的,不同视图可以采用不同的名字。
完整示例
这个示例包含了本篇的所有知识,并演示了不同名字的全局变量其实是同一个对象:
import SwiftUI
class EnvModel: ObservableObject{
@Published var info = "env"
@AppStorage("setting") var setting = "setting"
}
struct SwiftUIViewEnv: View {
@Binding var info : String
@EnvironmentObject var env: EnvModel
@EnvironmentObject var env2: EnvModel
var body: some View {
VStack{
Text(info)
Text(env.info)
.onTapGesture {
env.info += "1"
}
Text(env.setting)
.onTapGesture {
env.setting += "1"
}
Text(env2.info)
.onTapGesture {
env2.info += "a"
}
Text(env2.setting)
.onTapGesture {
env2.setting += "a"
}
}
}
}
#Preview {
var info = "abc"
SwiftUIViewEnv(info: Binding.constant(info)).environmentObject(EnvModel())
}
初始时两个字符串“env”回到原始状态,两个“setting”保持上次的状态(因为自动持久化):

再点一点增加信息:

两组信息始终是相同的。
网硕互联帮助中心


评论前必须登录!
注册