skip to Main Content

I’m trying to change the colors of an animated NavigationLink when another button pressed. NavigationLink background has two different colors constantly changing in animation and I want to change these two colors when I click a button without stopping the animation.

import SwiftUI

struct FirstView: View {
    
    @State var animate: Bool = false
    
    @State var secondaryColor: Color = Color("SecondaryAccentColor")
    @State var primaryColor: Color = Color("AccentColor")
    
    var body: some View {
        ScrollView {
            VStack(spacing: 10) {
                
                Text("Click on the Navigate button to go to the next page!")
                    .font(.title)
                    .fontWeight(.semibold)
                
                Text("Click on the Color button to change the colors!")
                    .padding(.bottom, 25)
                
                NavigationLink(
                    destination: NextPage(),
                    label: {
                        Text("NAVIGATE")
                            .foregroundColor(.white)
                            .font(.title3)
                            .fontWeight(.bold)
                            .frame(height: 60)
                            .frame(maxWidth: .infinity)
                            .background(animate ? secondaryColor : primaryColor)
                            .cornerRadius(15)
                    })
                .padding(.horizontal, 70)
                .shadow(
                    color: animate ? secondaryColor.opacity(0.4) : primaryColor.opacity(0.4),
                    radius: 15,
                    x: 0,
                    y: 30)
                
                
                Spacer()
                
                Button(action: {
                     
                    //CODE FOR THE CHANGING COLORS
                    
                })
                {
                    Text("Color")
                }
                   
            }
            .frame(maxWidth: 400)
            .multilineTextAlignment(.center)
            .padding(30)
            .onAppear(perform: addAnimation)
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity)
    }
    
    
    func addAnimation() {
        guard !animate else { return }
        DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
            withAnimation(
            Animation
                .easeOut(duration: 0.5)
                .repeatForever()
            ) {
                animate.toggle()
            }
        }
    }
    
}

struct FirstView_Previews: PreviewProvider {
    static var previews: some View {
        NavigationView {
            FirstView()
                .navigationTitle("Hi")
        }
    }
}

I’ve tried to do this but it didn’t work:

Button(action: {
                     
                    primaryColor = Color.red
                    secondaryColor = Color.yellow

                })
                {
                    Text("Color")
                }

When I do this color of the NavigationLink changes to only yellow and animation stops.

2

Answers


  1. Chosen as BEST ANSWER

    It works when I add the withAnimation to the button like this:

    Button(action: {
                     
    primaryColor = Color.red
    secondaryColor = Color.blue
    withAnimation(
              Animation
                  .easeOut(duration: 0.5)
                  .repeatForever()
              ) {
                  animate.toggle()
              }
                    
                })
                {
                    Text("Color")
                }
    

  2. as Curious Jorge said, i’m using Xcode 15 and it’s working.

    import SwiftUI
    
    struct ContentView: View {
        
        @State var animate: Bool = false
    
        
        @State var primaryColor: Color = Color.yellow
        @State var secondaryColor: Color = Color.red
        
        var body: some View {
            ScrollView {
                VStack(spacing: 10) {
                    
                    Text("Click on the Navigate button to go to the next page!")
                        .font(.title)
                        .fontWeight(.semibold)
                    
                    Text("Click on the Color button to change the colors!")
                        .padding(.bottom, 25)
                    
                    NavigationLink(
                        destination: NextPage(),
                        label: {
                            Text("NAVIGATE")
                                .foregroundColor(.white)
                                .font(.title3)
                                .fontWeight(.bold)
                                .frame(height: 60)
                                .frame(maxWidth: .infinity)
                                .background(animate ? secondaryColor : primaryColor)
                                .cornerRadius(15)
                        })
                    .padding(.horizontal, 70)
                    .shadow(
                        color: animate ? secondaryColor.opacity(0.4) : primaryColor.opacity(0.4),
                        radius: 15,
                        x: 0,
                        y: 30)
                    
                    
                    Spacer()
                    
                    Button(action: {
                        primaryColor = Color.green
                        secondaryColor = Color.black
                        
                    })
                    {
                        Text("Color")
                            .foregroundColor(.pink)
                        
                    }
                    
                }
                .frame(maxWidth: 400)
                .multilineTextAlignment(.center)
                .padding(30)
                .onAppear(perform: addAnimation)
            }
            .frame(maxWidth: .infinity, maxHeight: .infinity)
        }
        
        
        func addAnimation() {
            guard !animate else { return }
            DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
                withAnimation(
                    Animation
                        .easeOut(duration: 0.5)
                        .repeatForever()
                ) {
                    animate.toggle()
                }
            }
        }
        
    }
    
    struct FirstView_Previews: PreviewProvider {
        static var previews: some View {
            NavigationView {
                ContentView()
                    .navigationTitle("Hi")
            }
        }
    }
    
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search