简体   繁体   中英

Can't dismiss modal in SwiftUI

I have been having issues dismissing some modal views in SwiftUI and made the following example to illustrate the problem.

Below we have 4 views. The idea is that the App file will have a switch and decide which view to display based on that Switch's viewForDisplay property.

Initially we display the FirstView which modally presents the SecondView which then modally presents the ThirdView. When the ThirdView sets the viewForDisplay to.fourthView I would expect all the views in the FirstView/SecondView/ThirdView stack to go away and just see the FourthView. However it is showing the SecondView.

enum ViewForDisplay {
    case firstView
    case fourthView
}

class ViewModel: ObservableObject {
    
    @Published var viewForDisplay: ViewForDisplay = .firstView
    
}

@main
struct ModalDismissApp: App {
    
    @ObservedObject var viewModel = ViewModel()
    
    var body: some Scene {
        WindowGroup {
            switch viewModel.viewForDisplay {
            case .firstView:
                FirstView(viewModel: viewModel)
            case .fourthView:
                FourthView()
            }
        }
    }
}

struct FirstView: View {
    
    @State var isPresented: Bool = false
    
    @ObservedObject var viewModel: ViewModel
    
    init(viewModel: ViewModel) {
        self.viewModel = viewModel
    }
    
    var body: some View {
        VStack {
            Text("First View")
            Button(action: {
                isPresented = true
            }, label: {
                Text("Present Second View Modally")
            })
        }
        .fullScreenCover(isPresented: $isPresented, content: {
            SecondView(viewModel: viewModel)
        })
        
    }
}

struct SecondView: View {
    
    @State var isPresented: Bool = false
    
    @ObservedObject var viewModel: ViewModel
    
    init(viewModel: ViewModel) {
        self.viewModel = viewModel
    }
    
    var body: some View {
        VStack {
            Text("Second View")
            Button(action: {
                isPresented = true
            }, label: {
                Text("Present Third View Modally")
            })
        }
        .fullScreenCover(isPresented: $isPresented, content: {
            ThirdView(viewModel: viewModel)
        })
    }
}

struct ThirdView: View {
    
    @ObservedObject var viewModel: ViewModel
    
    init(viewModel: ViewModel) {
        self.viewModel = viewModel
    }
    
    var body: some View {
        VStack {
            Text("Third View")
            Button(action: {
                viewModel.viewForDisplay = .fourthView
            }, label: {
                Text("Dismiss Modals and go to Fourth View")
            })
        }
    }
}

struct FourthView: View {
    var body: some View {
        Text("Fourth View")
    }
}

This only happens when two levels of modal are applied. For example, if I were to set the viewForDisplay to.fourthView from the SecondView everything works fine. But for some reason when I have more than one modal it doesn't work.

I can work around this by dismissing the ThirdView and then setting the.viewForDisplay property but that gives me an undesirable animation. I just want to go directly to my FourthView and not sure why with multiple modals this is an issue.

在此处输入图像描述

You first need to dismiss all the presented controllers and then switch to the fourth view.

Here is the easy possible solution.

In the 3rd view, before switching to the fourth view, just dismiss all views.

struct ThirdView: View {
    
    @ObservedObject var viewModel: ViewModel
    
    init(viewModel: ViewModel) {
        self.viewModel = viewModel
    }
    
    var body: some View {
        VStack {
            Text("Third View")
            Button(action: {
                UIApplication.shared.windows.first?.rootViewController?.dismiss(animated: true, completion: {
                    
                }) //<-- Dismisss all view
                viewModel.viewForDisplay = .fourthView
            }, label: {
                Text("Dismiss Modals and go to Fourth View")
            })
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM