In the following lines of code, I tap a button and an alert message will appear. I wonder if I can change the code such that the alert message will appear after some time, say, 5 seconds? During this period of delay, I want to determine whether or not the app should show an alert message.
import SwiftUI
import Combine
struct ContentView: View {
@State var cancellables = Set<AnyCancellable>()
@State var disabled: Bool = false
@State private var showingAlert = false
let timeInterval: Double = 5.0
var body: some View {
VStack {
Spacer()
Button("Tap me") {
showingAlert = true
disabled = true
// some Combine work //
}
.font(.system(size: 24.0))
.disabled(disabled)
.alert("GGGG", isPresented: $showingAlert) {
/* showing alert after timeInterval */
}
}
}
}
I could do it in UIKit, but I'm not sure if that's possible in SwiftUI.
Muchos thankos.
I've figured out a way of doing it with StateObject. It's something like the following.
import SwiftUI
import Combine
struct ContentView2: View {
@State var disabled: Bool = false
@StateObject var delayMonitor = DelayMonitor()
@State private var showingAlert = false
var body: some View {
VStack {
Spacer()
Button("Tap to connect me") {
disabled = true
delayMonitor.start()
}
.font(.system(size: 24.0))
.disabled(disabled)
Spacer()
.frame(height: 30.0)
}.onChange(of: delayMonitor.failed) { newValue in
print("You've failed?: \(newValue)")
disabled = !newValue
showingAlert = newValue
}
.alert("Something is wrong...", isPresented: $showingAlert) {
Button("OK", role: .cancel) { }
}
}
}
class DelayMonitor: ObservableObject {
var timer = Timer()
var seconds: Double = 0.0
@Published var failed: Bool = false
func start() {
timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true, block: { _ in
self.seconds += 1.0
if self.seconds == 5.0 { // arbitrary timeout
self.timer.invalidate()
DispatchQueue.main.async() {
[weak self] in
guard let strongSelf = self else { return }
strongSelf.failed = true
}
}
})
}
}
The onChange guy will let me know only if the value (delayMonitor.failed) has changed. Since its initial value is set to false, I'll get a call only if it changes to true.