Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 如何在SwiftUI NavigationView中重新初始化类_Ios_Swift_Swiftui - Fatal编程技术网

Ios 如何在SwiftUI NavigationView中重新初始化类

Ios 如何在SwiftUI NavigationView中重新初始化类,ios,swift,swiftui,Ios,Swift,Swiftui,我有两个视图-主视图和详细视图。打开DetailView时,我初始化了一个跟踪视图数据的新类(在实际实现中,DetailView涉及一个游戏) 但是,当我从DetailView按back按钮返回MasterView,然后按按钮返回DetailView时,我的类没有改变。然而,每当我从MasterView移动到DetailView时,我想重新初始化这个类的一个新副本(在我的情况下是重新开始游戏) 我已将问题浓缩为以下代码: import SwiftUI import Combine class

我有两个视图-主视图和详细视图。打开DetailView时,我初始化了一个跟踪视图数据的新类(在实际实现中,DetailView涉及一个游戏)

但是,当我从DetailView按back按钮返回MasterView,然后按按钮返回DetailView时,我的类没有改变。然而,每当我从MasterView移动到DetailView时,我想重新初始化这个类的一个新副本(在我的情况下是重新开始游戏)

我已将问题浓缩为以下代码:

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、设置、视图状态等等。这就是一切开始的地方
  • “当前游戏”。。。。嗯,它可能是一个
    结构
    ,一个
    ,甚至是
    可观察对象
    中的属性
我想就是这样。在层次结构上,您的模型可以是:

视图状态

…玩家

……属性,包括ID和历史记录

…当前游戏

。。。。。。属性,包括难度

请注意,我已经更改了一些名称,并且对属性的定义非常模糊。关键是,您可以将所有的封装到
可观察对象中,创建一个它的`环境对象',并让您的所有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