我试图在SwiftUI中使用新的导航功能,现在我在NavigationLink中遇到了类似的早期问题,当目标视图创建了两次以上时。你能帮我找到正确的解决方案吗。
enum Step: String, Identifiable {
case page1
case page2
case page3
var id: String {
self.rawValue
}
}
class Router: ObservableObject {
@Published var steps: [Step] = []
static let shared = Router()
private init(){}
func showPage1() {
steps.append(.page1)
}
func showPage2() {
steps.append(.page2)
}
func showPage3() {
steps.append(.page3)
}
func popToRoot() {
steps.removeAll()
}
}
class BaseStepViewModel: ObservableObject {
let step: Step
let router: Router
init(step: Step, router: Router) {
self.step = step
self.router = router
print("Created step (step.rawValue)")
}
func shopNextPage() {
router.showPage2()
}
}
class Step1ViewModel: BaseStepViewModel { }
class Step2ViewModel: BaseStepViewModel {
override func shopNextPage() {
router.showPage3()
}
}
class Step3ViewModel: BaseStepViewModel {
override func shopNextPage() {
router.popToRoot()
}
}
struct StepView: View {
@StateObject var viewModel: BaseStepViewModel
var body: some View {
Button {
viewModel.shopNextPage()
} label: {
Text(viewModel.step.rawValue)
}
}
}
class WelcomeViewModel: ObservableObject, Identifiable {
let title: String
let router: Router
var id: String {
title
}
init(title: String, router: Router) {
self.title = title
self.router = router
print("Created welcome view")
}
func startFlow() {
router.showPage1()
}
}
struct WelcomeView: View {
@StateObject var viewModel: WelcomeViewModel
var body: some View {
Button {
viewModel.startFlow()
} label: {
Text(viewModel.title)
}
}
}
struct RootView: View {
@StateObject var router = Router.shared
var body: some View {
NavigationStack(path: $router.steps) {
WelcomeView(viewModel: .init(title: "Welcome", router: router))
.id("Welcome")
.navigationDestination(for: Step.self) { step in
switch step {
case .page1:
StepView(viewModel: Step1ViewModel(step: step, router: router))
case .page2:
StepView(viewModel: Step2ViewModel(step: step, router: router))
case .page3:
StepView(viewModel: Step3ViewModel(step: step, router: router))
}
}
}
}
}
正如您所看到的,WelcomeViewModel创建了多次。我试图添加一个特定的id来使view/viewModel唯一,但没有帮助。
方法:
- 当您从外部传递StateObject时,请使用
StateObject(wrappedValue:)
对其进行初始化,如下所示
代码:
struct WelcomeView: View {
@StateObject var viewModel: WelcomeViewModel
init(viewModel: WelcomeViewModel) {
_viewModel = StateObject(wrappedValue: viewModel)
}
var body: some View {
Button {
viewModel.startFlow()
} label: {
Text(viewModel.title)
}
}
}