Ios 如何在SwiftUI NavigationView中重新初始化类
我有两个视图-主视图和详细视图。打开DetailView时,我初始化了一个跟踪视图数据的新类(在实际实现中,DetailView涉及一个游戏) 但是,当我从DetailView按back按钮返回MasterView,然后按按钮返回DetailView时,我的类没有改变。然而,每当我从MasterView移动到DetailView时,我想重新初始化这个类的一个新副本(在我的情况下是重新开始游戏) 我已将问题浓缩为以下代码:Ios 如何在SwiftUI NavigationView中重新初始化类,ios,swift,swiftui,Ios,Swift,Swiftui,我有两个视图-主视图和详细视图。打开DetailView时,我初始化了一个跟踪视图数据的新类(在实际实现中,DetailView涉及一个游戏) 但是,当我从DetailView按back按钮返回MasterView,然后按按钮返回DetailView时,我的类没有改变。然而,每当我从MasterView移动到DetailView时,我想重新初始化这个类的一个新副本(在我的情况下是重新开始游戏) 我已将问题浓缩为以下代码: import SwiftUI import Combine class
import SwiftUI
import Combine
class Model: ObservableObject {
@Published var mytext: String = "mytext"
}
struct MasterView: View {
var body: some View {
NavigationView {
NavigationLink(destination: DetailView(model: Model())) {
Text("press me")
}
}
}
}
struct DetailView: View {
@ObservedObject var model: Model = Model()
var body: some View {
TextField("Enter here", text: $model.mytext)
}
}
struct MasterView_Previews: PreviewProvider {
static var previews: some View {
MasterView()
}
}
每次单击“导航”链接到“详细信息”视图时,我都想创建一个新的Model
实例,但它似乎总是引用同一个原始实例-我可以通过在“详细信息”视图的文本字段中键入一个更改来看到这一点,如果我再次返回并向前,该更改将持续存在
有什么方法可以做到这一点吗?根据你的评论——并纠正我的错误——以下是我的设置方法 你的需要是:
- “基本”阶级。将其称为MasterView、设置、视图状态等等。这就是一切开始的地方
- “当前游戏”。。。。嗯,它可能是一个
,一个结构
,甚至是类
中的属性可观察对象
可观察对象中,创建一个它的`环境对象',并让您的所有SwiftUI视图对其中的更改作出“反应”
撇开视图不谈,希望您能看到这个“模型”在哪里可以包含几乎所有您希望执行所有操作的Swift代码—现在您所需要的就是绑定视图
(1) 创建您的可观察对象
。它需要(a)是类对象,并且(b)符合可观察对象
协议。这里有一个简单的例子:
class ViewState : ObservableObject {
var objectWillChange = PassthroughSubject<Void, Never>()
@Published var playerID = "" {
willSet {
objectWillChange.send()
}
}
}
请注意,这里添加了一行,ViewState
只实例化了一次
(3) 最后,在任何需要了解视图状态的SwiftUI视图中,通过添加一行代码将其绑定:
@EnvironmentObject var model: ViewState
如果您愿意,您可以在您的模型(ViewState
)中执行任何操作,例如实例化新游戏、标记某些内容以生成模式弹出窗口、将玩家添加到阵列等等
我希望解释的主要问题是,不需要实例化第二个视图状态,而需要在单个视图状态中实例化第二个游戏实例
再说一次,如果我离你的需求很远,请告诉我——我很乐意删除我的答案。祝你好运 没有真正尝试重复这一点,我认为您的问题在于初始化-即,DetailView(model:model()
在您传递给DetailView
的内容中。如果您使用的是SwiftUI,为什么不创建EnvironmentObject
?(您不需要,但这样做会更简单。)这就是model()
-尤其是()
这一块-在我看来,它像是在欺骗你。这就是“创建一个“新实例”或“引用相同的原始实例”“您指的是。创建模型的一个实例并在整个过程中使用它。抱歉,第二条评论-如果您需要,我可以发布更好的代码来执行此操作。我没有想过通过环境传递数据,但我不清楚这里是否需要。我只需要一个视图(DetailView)中的model()对象。”,所以环境不会有帮助。另外,环境(我的理解方式)我只会有一个实例,但我特别希望有多个实例。我在MasterView中传递模型的原因是因为在我的代码中,我实际上有几个导航链接-每个链接都有一个特定的模型实例,例如DetailView(model(settings=a))
和DetailView(model(settings=b))
我不明白-为什么您需要模型的多个实例?这听起来……错了。如果模型==AppState
,我还缺少什么?另一种说法是(使用UIKit而不是SwiftUI,但这并不重要),假设您有三个视图控制器-A、B和C。它们都嵌入到UINavigationController中。VC“A”有一个按钮,上面写着“按我”,完成后,VC“B”显示一个文本字段,该字段被传递给VC“C”使用。这就是你想要的吗?如果是的话,为什么你需要不止一个实例?我肯定我遗漏了一些东西。如果不清楚,很抱歉-这是我第一次构建这样的应用程序,所以它可能不是最佳架构,但我感谢你的帮助!我正在构建一个游戏,MasterView
是我的主菜单您可以点击难度级别(每个级别由DetailView
显示)。Model
存储单个游戏的变量,包括难度级别(这就是我所说的settings=a
等)这就是为什么,回到主菜单中,再次单击游戏,我希望它重新启动,我想通过传递一个新的Model
实例来实现这一点。这更有意义吗?谢谢!我看到了环境是如何使事情变得更简单的。不过,最后一件事是——我如何才能在ho上创建一个按钮呢me view选择一个难度级别并在新视图中开始一个新游戏(如您所说的,在单视图状态中实例化第二个游戏)?我应该使用NavigationLink还是其他什么?@mxt533,我要做的第一件事是在您的模型中创建一个函数来完成它。(UI和逻辑分离。)现在,您只需在UI中创建一个按钮并设置
@EnvironmentObject var model: ViewState