Home > Mobile >  SwiftUI - Opening sheet without button click
SwiftUI - Opening sheet without button click

Time:07-15

I am able to sheet over current view when I click on a button.

However I have scenarios where I query for data and as soon as data is received, instead of showing a message in the view, I wish to open a sheet programmatically without any user interaction and show a short message on the sheet to let the user know that their action was successful. My code for opening the sheet programmatically isn't working.

Code for opening sheet via button click(this code works):

import SwiftUI

struct CustomView: View {
    @State var showingModal: Bool = false
    
    var body: some View {
        VStack {
            CustomButton(imageName: imageName, action: { self.showingModal.toggle() })
            .sheet ( isPresented: $showingModal,
                content: {
                    let messageViewDetails = getMessageViewDetails()

                    ShowMessageAlert(rawValue: messageViewDetails.actionType.rawValue)?.showGeneralMessageView(messageText: messageViewDetails.messageText, showingModal: $showingModal)
                }
            )
        }
    }

    // func for getMessageViewDetails
}

Below 2 structs is the code for opening sheet programmatically:

import SwiftUI

struct OtherCustomView: View {
    @ObservedObject var viewModel: CustomViewModel

    var body: some View {
        VStack {
            VStack {
                HStack {
                    Spacer()
                    Text("Hello World").font(.callout).foregroundColor(Color.white)
                    Spacer()
                }
            }.padding(.bottom, 10).padding(.top, 10)

            // Removed other states to keep the code short and easy to understand
            switch viewModel.state {
            case .idle:
                Color.clear.onAppear(perform: { viewModel.getData() })
            case .loading:
                ProgressView()
            case .response(let isSuccess, let result):
                ShowResponseView(isSuccess: isSuccess, result: result)
            }
        }.navigationBarTitle("Back")
        .onDisappear() {
            viewModel.state = .idle
        }
    }
}

// Code for ShowResponseView which will be reused for other states as well in OtherCustomView

import SwiftUI

struct ShowResponseView: View {
    @State var showingModal: Bool = false
    var isSuccess: Bool = false
    var result: CustomModel

    var body: some View {
        VStack {
            let _ = NSLog("Within VStack of ShowResponseView")
            Text("")
        }.onAppear(perform: {
            self.showingModal.toggle()
        }).sheet(isPresented: $showingModal, content: {
            let messageViewDetails = getMessageViewDetails()

            let _ = NSLog("Within sheet of ShowResponseView")
            ShowMessageAlert(rawValue: messageViewDetails.actionType.rawValue)?.generalMessageView(messageText: messageViewDetails.messageText, showingModal: $showingModal)
        })
    }

    // func for getMessageViewDetails
}

Whenever response is received, code within .response of OtherCustomView gets executed which calls ShowResponseView. I see "Within VStack of ShowResponseView" debug statement getting printed on console, but I never see "Within sheet of ShowResponseView". I also added debug statement within .onAppear() and I see that being printed too. I just don't see the sheet being presented.

Am I doing anything wrong here? How do I present a sheet programmatically?

Note: Working on watch app and on watchOS 7.0 version. Xcode - 13.4.1

CodePudding user response:

From what I tested, your "self.showingModal.toggle()" never did anything.

However, if whenever you call the "ShowResponseView(isSuccess: isSuccess, result: result)", you make the sheet appears automatically by toggle() the "showingModal", why not just pass true value to the "showingModal" variable?

I did this:

 ShowResponseView(showingModal: true)

Then, the sheet appeared normally, and "Within sheet of ShowResponseView" was also printed.

  • Related