quanshousio / ToastUI

A simple way to show toast in SwiftUI.
MIT License
566 stars 45 forks source link

Showing ToastUI on app load #30

Open rursache opened 2 years ago

rursache commented 2 years ago

Pre-requisites:

Expected Behavior

Be able to show the ToastUI at app load. Useful when doing initial network requests like auth or other early tasks

Current Behavior

Currently the ToastUI does not appear

Steps to Reproduce

struct TestView: View {
    @State private var isLoading: Bool = false

    var body: some View {
        VStack {
            Text(isLoading ? "Please wait..." : "Got auth token")
                .padding()
            Spacer()
        }
        .toast(isPresented: $isLoading) {
            ToastView("Loading").toastViewStyle(.indeterminate)
        }
        .onAppear {
            self.isLoading = true
        }
    }
}

Context

I basically want to open the app and the ToastUI to be visible until some network requests are done in the background Disclaimer: I'm still new to SwiftUI so i might try to achieve this the wrong way

Your Environment

rursache commented 2 years ago

UPDATE: It works if i do:

.onAppear {
  DispatchQueue.main.async {
    self.isLoading = true   
  }
}

Seems like it's not ToastUI's fault but by own lack of SwiftUI understanding 😞

quanshousio commented 2 years ago

This is actually an issue, not because of your lack of SwiftUI understanding. SwiftUI presentations such as .sheet and .alert can be presented in onAppear, so I do expect ToastUI to follow the same behavior. I have found the culprit but not sure how to implement a fix yet.

I also found another bug where if you initialize the @State variable with true then ToastUI will not present the toast. For now, you can safely use DispatchQueue.main.async in onAppear as the workaround. Thanks for the report.

rursache commented 2 years ago

I actually got it working as i want it to work!

@State var isLoading: Bool = false

then on my view, i have this:

.toast(isPresented: $isLoading) {
    ToastView("Loading").toastViewStyle(.indeterminate)
}
.task {
    self.isLoading = true
    await apiCall()
    self.isLoading = false
}

works fine and feels like the SwiftUI way of doing it

EDIT

I also found another bug where if you initialize the @State variable with true then ToastUI will not present the toast

I can confirm this is also true. That's why I start with the @State property as false