将SwiftUI存储视图作为变量传递给它一些绑定

将SwiftUI存储视图作为变量传递给它一些绑定,swift,swiftui,Swift,Swiftui,我想将一个视图存储为一个变量供以后使用,同时传递该视图一些绑定。 以下是我尝试过的: struct Parent: View { @State var title: String? = "" var child: Child! init() { self.child = Child(title: self.$title) } var body: some View { VStack { child

我想将一个
视图
存储为一个变量供以后使用,同时传递该
视图
一些
绑定
。 以下是我尝试过的:

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 {
        // ...
    }
}

我不知道这是否是一个bug,但是直接初始化
body
属性中的子项就可以了。但是,我需要将该子对象作为属性来访问其方法。

这与SwiftUI框架的设计背道而驰。您不应该有任何可调用方法的持久视图。相反,视图会根据需要创建和显示,以响应应用程序的状态变化

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")
            }
        }
    }
}
将您的数据封装在一个
observateObject
模型中,并实现您需要调用该模型的任何方法

更新

可以在
Child
中定义这样一个函数,但是您应该只从
Child
结构定义中调用它。例如,如果子视图包含按钮,则该按钮可以调用子视图的实例方法。比如说,

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")
            }
        }
    }
}

如果您想从父级为子级更改某些内容,绑定是正确的方法。如果这很复杂,您必须使用数据模型

struct Parent: View {
@State var title: String? = ""

var body: some View {
    VStack {
        Child(title: $title)
        Button(action: {
            self.title = "something"
        }) {
           Text("click me")
        }
    }
}
}

 struct Child: View {
@Binding var title: String?
var body: some View {
    Text(title ?? "")
}
}

您不想使用ObserveObject吗?它将通过引用传递,这样的问题应该会消失吗?@Asperi我希望子对象存储为变量,因为它包含一些我想从父对象调用的函数,我了解子对象,我的意思是,在这种情况下,不是使用
@State
@Asperi,而是使用
@State
?我的意思是,我仍然使用
$title
传递对变量的引用。我想说,如果您想像现在这样存储
子项
,应该有更好的方法。这样做通常会导致模式中断,为以后的维护带来不必要的工作。谢谢你的回答,我用更多的代码更新了我的问题。我在问题中提供了一个基本示例,但在我的应用程序中,它涉及到复杂的工作,包括网络调用,这就是为什么我必须调用functionView is view。网络数据处理不是视图,对吗?您可以在DataModel中执行此操作,然后在视图中放置一个支架,或者在数据非常复杂的情况下通过ViewModel链接到视图。