0

There are 2 pages in the demo

  1. main view with a navigation button to the the content view
  2. content view has a image overlaying a border animation.

the problem is if it starts from launching app, then clicking the button, then it's weird of the animation part however, if it's already launched, e.g. back to main page from content view, then go to content view again, the behavior is as expectation also, i tested, if remove the main view and directly launch from the content view, the behavior is good.

So i guess there's magic in navigationstack break something. What's the reason and how to fix it?

here's the code and screen record

import SwiftUI

@main
struct TestSwiftuiApp: App {
    @StateObject var navManager = NavManager()

    var body: some Scene {
        WindowGroup {
            MainView()
                .environmentObject(navManager)
        }
    }
}

struct MainView: View {
    @EnvironmentObject var navManager: NavManager

    var body: some View {
        NavigationStack(path: $navManager.path) {
            ZStack {
                VStack {
                    Button("click to new page") {
                        navManager.path.append("ContentView")
                    }
                }
            }
            .navigationDestination(for: String.self) { destination in
                let a = print("destination \(destination)")
                if destination == "ContentView" {
                    ContentView()
                }
            }
        }
    }
}

class NavManager: ObservableObject {
    @Published var path = NavigationPath()
    
    public func backToMain() {
        path.removeLast(path.count)
    }
}

struct ContentView: View {
    var body: some View {
        VStack {
            Image(systemName: "globe")
                .imageScale(.large)
                .foregroundColor(.accentColor)
                .overlay(
                    CardGradient(gradient: Gradient(colors: [.red, .yellow, .blue]),
                                 duration: 1)
                )
        }
    }
}

struct CardGradient: View {
    let gradient: Gradient
    let width: CGFloat
    let duration: Double
    
    @State var animation = false
    
    init(gradient: Gradient, width: CGFloat = 5, duration: Double = 2) {
        self.gradient = gradient
        self.width = width
        self.duration = duration
    }
    
    var body: some View {
        Rectangle()
            .stroke(
                LinearGradient(gradient: gradient,
                               startPoint: animation ? .topLeading : .bottomLeading,
                               endPoint: animation ? .bottomTrailing : .topTrailing),
                lineWidth: width
            )
            .animation(.linear(duration: duration).repeatForever(), value: animation)
            .border(.black, width: 3)
            .onAppear {
                animation = true
            }
    }
}

enter image description here

CodeBoy
  • 591
  • 6
  • 12
  • 1
    Relevant info here: https://stackoverflow.com/questions/64566492/swiftui-broken-explicit-animations-in-navigationview – jnpdx Apr 10 '23 at 16:50

0 Answers0