Reputation: 11
I am learning swiftUI. I have created a sample demo that contains 2 screens. first one is a splash screen and another is the login screen. In the splash screen, I used a timer with an interval of 5 seconds. when the count reaches 0 I want to redirect to the login screen.
the problem is Login screen redirecting multiple times.
here is starting Point
struct RoutingDemo_SwiftUIApp: App {
@StateObject private var router = Router()
var body: some Scene {
WindowGroup {
NavigationStack(path: $router.navPath) {
SpashScreen().navigationDestination(for: Router.Destination.self, destination: { destination in
switch destination {
case .dashboardView:
TempView()
case .login:
LoginView().navigationTitle("")
.navigationBarBackButtonHidden()
}
})
}.environmentObject(router)
}
}
}
here is code of splash screen
struct SpashScreen: View {
@EnvironmentObject var router: Router
var body: some View {
TimerView(callBack: {
router.navigate(to: .login)
})
}
}
#Preview {
SpashScreen()
}
struct TimerView: View {
@State private var countDown = 5
var timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
var callBack: (() -> Void)
var body: some View {
VStack {
if let url = Bundle.main.url(forResource: "provider_splash", withExtension: "gif") {
KFAnimatedImage(url).scaledToFill().frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height).ignoresSafeArea(.all)
}
}.onReceive(timer) { _ in
if countDown > 0 {
countDown -= 1
} else {
timer.upstream.connect().cancel()
callBack()
}
}
}
}
here is code of LoginView
struct LoginView: View {
var body: some View {
Button("Login", action: {
})
}
}
here is code of router
final class Router: ObservableObject {
public enum Destination: Codable, Hashable {
case login
case dashboardView
}
@Published var navPath = NavigationPath()
func navigate(to destination: Destination) {
navPath.append(destination)
}
func navigateBack() {
navPath.removeLast()
}
func navigateToRoot() {
navPath.removeLast(navPath.count)
}
}
I have tried to seperate timer view code from envirment object because updating envirment object cases swiftUI redraw entire view.
Upvotes: 1
Views: 60
Reputation: 30746
Just remove the Router object and use multiple .navigationDestination for each type of thing you want to show.
Remove onReceive and use TimelineView for your counter.
Upvotes: 0