ios SwiftUI -关闭视图,应用程序返回内容视图而不是上一个视图

ykejflvf  于 2023-02-14  发布在  iOS
关注(0)|答案(1)|浏览(158)

我的应用程序中有3个视图,单击每个视图上的按钮会打开一个新视图。当单击第3个视图上的按钮时,我希望关闭第3个视图,并显示第2个视图。但是,我注意到应用程序导航回第一个视图,而不是第2个视图。
注意:我有很多元素,因此我的应用程序中有很多代码。我删除了所有这些元素,并在这里添加了最少的工作代码,我仍然能够重现这个问题。

// *** Main App***

@main
struct sample_sampleApp: App {
    var body: some SwiftUI.Scene {
        WindowGroup {
            NavigationView {
                ContentView().ignoresSafeArea()
            }.navigationViewStyle(.stack)
        }
    }
}

// *** Content View or First View***

import SwiftUI

struct ContentView: View {
    @State private var goToView2 = false

    var body: some View {
        VStack {
            NavigationLink(destination: View2(), isActive: $goToView2) {
                Button(action: { goToView2.toggle() }) {
                    Text("This is first view - Click to go to View 2").foregroundColor(.red).font(.title)
                }
            }
        }
    }
}

// *** View2 View***

import SwiftUI
import Combine

struct View2: View {    
    @ObservedObject var viewModel: View2ViewModel = View2ViewModel()

    var body: some View {
        VStack {
            switch viewModel.state {
            case .showView2:
                VStack(alignment: .leading, spacing: 8) {
                    Button(action: { viewModel.navigateToView3() } ) {
                        Text("Second View - Click to go to View 3").foregroundColor(.blue).font(.title)
                    }
                }
            case .showView3:
                View3()
            }
        }
        .onAppear() {
            viewModel.isViewVisible = true
            viewModel.doSomething()
        }
        .onDisappear() {
            viewModel.isViewVisible = false
        }
    }
}

// *** View model for view 2***

class View2ViewModel: ObservableObject {
    enum View2AppState {
        case showView2
        case showView3
    }
    
    // UI changes when state gets updated.
    @Published var state: View2AppState = .showView2
    var isViewVisible = false
    
    func doSomething() {
        self.state = .showView2
    }
    
    func navigateToView3() {
        self.state = .showView3
    }
}

// *** View3***

struct View3: View {
    @ObservedObject var viewModel: View3ViewModel = View3ViewModel()
    @Environment(\.dismiss) var dismiss
    
    var body: some View {
        VStack {
            switch viewModel.state {
            case .showView3:
                VStack(alignment: .leading, spacing: 8) {
                    Button(action: { dismiss() } ) {
                        Text("Third View - Click to dismiss this and to go back to view 2").foregroundColor(.green).font(.title)
                    }
                }
            }
        }
        .onAppear() {
            viewModel.isViewVisible = true
            viewModel.doSomething()
        }
        .onDisappear() {
            viewModel.isViewVisible = false
        }.navigationBarBackButtonHidden(true)
    }
}

// *** View model for view 3***

class View3ViewModel: ObservableObject {
    enum View3AppState {
        case showView3
    }
    
    // UI changes when state gets updated.
    @Published var state: View3AppState = .showView3
    var isViewVisible = false
    
    func doSomething() {
        self.state = .showView3
    }
}

不知道我做错了什么。以前我确实使用了dismiss()来消除工作表,它工作得很好,但在这种情况下不是这样。我在iOS 16. 0上运行这段代码,但我的测试应用程序设置为iOS 15作为最低版本。
编辑:我也在iOS15.0上测试过,也能在上面重现,所以我的代码一定有问题。不知道是什么。我在中使用NavigationView,导航视图样式为Stack。

2nc8po8w

2nc8po8w1#

当点击第3个视图上的按钮时,我希望关闭第3个视图,并应显示第2个视图。
让我们先看看view2的代码。

struct View2: View {    
    @ObservedObject var viewModel: View2ViewModel = View2ViewModel()

    var body: some View {
        VStack {
            switch viewModel.state {
            case .showView2:
                VStack(alignment: .leading, spacing: 8) {
                    Button(action: { viewModel.navigateToView3() } ) {
                        Text("Second View - Click to go to View 3").foregroundColor(.blue).font(.title)
                    }
                }
            case .showView3:
                View3()
            }
        }
    }
}

//  here viewModel.navigateToView3() is just changing this state
//  func navigateToView3() {
//        self.state = .showView3
//    }

当前代码行为,当点击导航到view3时,将view2的内容替换为view3,而不是实际导航到它。
因此,当调用dismiss函数时,它不应返回view2,因为它已经在view2显示view3的内容。
因此,根据代码,在dismiss印刷机上返回view1实际上是正确的行为。
如果您希望得到所要求的结果,请考虑使用传递到子视图的closure修改代码,以更改view2中的状态,或者浏览此answer以实际导航到它。

相关问题