Toast wont disappear
ch05enOne opened this issue ยท 9 comments
This library used to work for me but ever since I made some slight changes, once the toast appear, it never leaves. These are the options im using:
private let toastOptions = SimpleToastOptions(alignment: .bottom, hideAfter: 4, showBackdrop: false, backdropColor: Color.clear, animation: .easeInOut, modifierType: .slide)
Thanks for the info. Your options are fine, the bug was on my side.
I just released a version (0.2.1) that should fix your problem.
@sanzaru Unfortunately, the toast doesn't disappear for me anymore. I'm using version 0.2.2 on iOS 14.5. Quite a few things broke in 14.5 (e.g. with NavigationLink) so you may want to revisit this again. Here's my full modifier class, I'm always using it with :
import Design
import SwiftUI
import SimpleToast
import SFSafeSymbols
fileprivate struct Toast: ViewModifier {
let isPresented: Binding<Bool>
let icon: SFSymbol
let message: LocalizedStringKey
@Environment(\.colorScheme) var colorScheme
func body(content: Content) -> some View {
content
.simpleToast(
isShowing: isPresented,
options: SimpleToastOptions(
alignment: .bottom,
hideAfter: 2.5, // <-- this should make it hide after 2.5 seconds, but it doesn't hide ...
showBackdrop: false,
animation: .linear,
modifierType: .fade
)
) {
Label(message, systemSymbol: icon)
.textStyle(.body(semibold: false, italic: false))
.padding()
.background(
ZStack {
VisualEffectView(effect: UIBlurEffect(style: .prominent))
Color.blue.opacity(0.1)
}
)
.foregroundColor(Color.blue.change(.luminance, to: colorScheme == .dark ? 0.66 : 0.33))
.cornerRadius(10)
.padding()
}
}
}
extension View {
func toast(isPresented: Binding<Bool>, icon: SFSymbol, message: LocalizedStringKey) -> some View {
modifier(Toast(isPresented: isPresented, icon: icon, message: message))
}
}
@Jeehut I tried to reproduce your problem, but for me your code is working fine and the toast disappears as desired.
I built some simple view with your modifier (i just commented out some designs of yours and changed the icon definition):
The problem you describe sounds like a problem with the binding you pass. On hiding the toast simply invalidates the timer, sets the binding back to false, the offset back to .zero and calls the completion function, if one was passed.
@sanzaru Thanks for the investigation. I will have a look into it, I just noticed while writing tests, that I'm actually receiving a new value for the binding, but the value is true
. I'll report again if I find another issue within SimpleToast, otherwise you can assume I found the issue in my code and fixed it. ๐
@sanzaru I actually couldn't find an issue with my Binding. I'm using TCA's binding
creator which looks something like this:
.toast(
isPresented: viewStore.binding(
get: { $0.showForgotPasswordToast },
send: LoginAction.setForgotPasswordToast(isPresented:)
),
type: .warning,
icon: .lockCircle,
message: "TODO: Open screen 'forgot password'"
)
Just for the sake of testing my binding, I passed nil
to the hideAfter
option and instead added an onChange
modifier with a simple delay function and it works now โ so my feeling is that the binding isn't wrong, just something gets lost in how things are passed here to SimpleToast
โ maybe it's missing a strong reference to the binding?
Here's my updated code:
import Design
import SwiftUI
import SimpleToast
import SFSafeSymbols
fileprivate struct Toast: ViewModifier {
let isPresented: Binding<Bool>
let icon: SFSymbol
let message: LocalizedStringKey
@Environment(\.colorScheme) var colorScheme
func body(content: Content) -> some View {
content
.simpleToast(
isShowing: isPresented,
options: SimpleToastOptions(
alignment: .bottom,
hideAfter: nil,
showBackdrop: false,
animation: .linear,
modifierType: .fade
)
) {
Label(message, systemSymbol: icon)
.textStyle(.body(semibold: false, italic: false))
.padding()
.background(
ZStack {
VisualEffectView(effect: UIBlurEffect(style: .prominent))
Color.blue.opacity(0.1)
}
)
.foregroundColor(Color.blue.change(.luminance, to: colorScheme == .dark ? 0.66 : 0.33))
.cornerRadius(10)
.padding()
}
.onChange(of: isPresented.wrappedValue) { value in
if isPresented.wrappedValue {
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 2.5) {
isPresented.wrappedValue = false
}
}
}
}
}
extension View {
func toast(isPresented: Binding<Bool>, icon: SFSymbol, message: LocalizedStringKey) -> some View {
modifier(Toast(isPresented: isPresented, icon: icon, message: message))
}
}