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

时间:2019-10-20 21:50:33

标签: ios swift swiftui

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

但是,当我从DetailView按下返回按钮返回到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()
    }
}

每次单击NavigationLink进入详细信息视图时,我都想创建一个Model的新实例,但是似乎它总是引用回相同的原始实例-我可以通过键入更改来查看进入DetailView的文本字段,如果我再次来回前进,该字段将保留。

有什么办法吗?

1 个答案:

答案 0 :(得分:1)

根据您的评论-并在错误之处纠正我-这是我的设置方式。

您的需求是:

  • “基本”类。将其命名为MasterView,“设置”,“视图状态”。这是一切的开始。
  • “当前游戏”。...好吧,它可能是structclass,甚至是ObservableObject中的属性。

我想就是这样。从层次上讲,您的模型可以为:

ViewState

...球员

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

...当前游戏

......属性,包括难度

请注意,我更改了一些名称,并且在属性上非常含糊不清。关键是,您可以将所有这些内容的全部封装在ObservableObject中,为其创建一个`EnvironmentObject,并使所有SwiftUI视图对其中的更改进行“反应”。

省略视图,希望您可以看到此“模型”可以包含几乎所有您想做的Swift代码-现在您需要的是绑定视图。

(1)创建您的ObservableObject需要(a)是一个类对象,(b)遵守ObservableObject协议。这是一个简单的例子:

class ViewState : ObservableObject {
    var objectWillChange = PassthroughSubject<Void, Never>()
    @Published var playerID = ""  {
        willSet {
            objectWillChange.send()
        }
    }
}

您可以创建更多的结构/类,并在模型中根据需要实例化它们。

(2)实例化ViewState 一次您的环境。在SceneDelegate中:

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    if let windowScene = scene as? UIWindowScene {
        let window = UIWindow(windowScene: windowScene)
        window.rootViewController = UIHostingController(rootView: ContentView()
            .environmentObject(ViewState())
        )
        self.window = window
        window.makeKeyAndVisible()
    }
}

请注意,这里添加了一行,并且ViewState实例化了一次。

(3)最后,在需要了解视图状态的 any SwiftUI视图中,通过添加一行代码来绑定它:

@EnvironmentObject var model: ViewState

如果愿意,您可以通过实例化新游戏,在模型(ViewState)中进行几乎任何操作,标记某些内容以产生模式弹出窗口,并将玩家添加到数组中等等。

我希望解释的主要事情是不需要实例化第二视图状态-而是在您的单一视图状态内实例化第二游戏实例。 / p>

再次,如果我无法满足您的需求,请告诉我-我很乐意删除我的答案。祝你好运!