swift - SwiftUI 将 View 存储为变量,同时传递一些绑定
问题描述
我想将 aView
作为变量存储以供以后使用,同时传递View
一些Bindings
. 这是我尝试过的:
struct Parent: View {
@State var title: String? = ""
var child: Child!
init() {
self.child = Child(title: self.$title)
}
var body: some View {
VStack {
child
//...
Button(action: {
self.child.f()
}) {
//...
}
}
}
}
struct Child: View {
@Binding var title: String?
func f() {
// complex work from which results a string
self.title = <that string>
}
var body: some View {
// ...
}
}
它可以正确编译View
并按预期显示,但是当从Binding
父级传递的子级更新时,变量永远不会更新。你甚至可以做这样的事情(从孩子):
self.title = "something"
print(self.title) // prints the previous value, in this case nil
我不知道这是否是一个错误,但直接在body
属性中初始化孩子就可以了。但是,我需要那个孩子作为一个属性来访问它的方法。
解决方案
这与 SwiftUI 框架的设计背道而驰。您不应该有任何持久视图来调用方法。相反,视图会根据需要创建和显示,以响应应用程序的状态变化。
将您的数据封装在ObservableObject
模型中,并实现您需要在该模型上调用的任何方法。
更新
可以在 中定义这样的函数Child
,但您应该只在Child
struct 定义中调用它。例如,如果您的子视图包含一个按钮,则该按钮可以调用子视图的实例方法。例如,
struct Parent: View {
@State private var number = 1
var body: some View {
VStack {
Text("\(number)")
Child(number: $number)
}
}
}
struct Child: View {
@Binding var number: Int
func double() {
number *= 2
}
var body: some View {
HStack {
Button(action: {
self.double()
}) {
Text("Double")
}
}
}
}
但是您不会尝试double()
从子结构外部调用。如果您想要一个可以全局调用的函数,请将其放入数据模型中。如果函数调用正在发出网络请求,则尤其如此,因为模型将停留在您的子视图之外,即使由于布局更改而重新创建它也是如此。
class NumberModel: ObservableObject {
@Published var number = 1
func double() {
number *= 2
}
}
struct Parent: View {
@ObservedObject var model = NumberModel()
var body: some View {
VStack {
Text("\(model.number)")
Button(action: {
self.model.double()
}) {
Text("Double from Parent")
}
Child(model: model)
}
}
}
struct Child: View {
@ObservedObject var model: NumberModel
var body: some View {
HStack {
Button(action: {
self.model.double()
}) {
Text("Double from Child")
}
}
}
}
推荐阅读
- javascript - 格式化数据和删除键
- ruby - 在 Ruby 中,如何从文件中维护一长串实例变量?
- java - 哪种签名算法可以处理 RSA 密钥?
- java - 难道不能保证从列表派生的并行流总是表现得像它的顺序对应物一样,提供相同的、可预测的输出吗?
- javascript - 使用 D3 检查时获取复选框的 ID
- node.js - 响应是空对象或来自 Nodejs 位置 0 的 JSON 中的 Unexpected token <
- swiftui - SwiftUI PresentationButton 在 watchOS 上单次使用后停止运行
- php - 如何使用货币(WHMCS)在模板中显示产品价格
- php - 使用 AJAX 将表单数据发送到 PHP 脚本并在不刷新页面的情况下弹出成功通知
- swift - 我们可以在警卫中进行功能返回类型条件检查吗?