swiftuiswitch-statementuiswitch

How do I add transitions between switch result cases?


Currently, my code uses a series of switch result cases that asks questions and presents different answer choices. For example, when the user clicks Evening, the code will present a new question with the answer choices being "Sweet" and "Savory". How can I put a cool transition where the "Morning" and "Evening" choices turn into the "Sweet" and "Savory" choices? Open to any transitions that you'd recommend.

var body: some View {
    
    let cardWidth = 300
    let cardWidthValue = CGFloat(cardWidth)
    
    let cardHeight = 300
    let cardHeightValue = CGFloat(cardHeight)
    
    VStack {
        ZStack {
            Rectangle()
                .fill(Color(red: 0.0, green: 0.5, blue: 1.0, opacity: 0.4))
                .frame(width: 350, height: 250)
                .cornerRadius(20)
                .shadow(color: .gray, radius: 20)
            
            switch result {
            case "Start":
                VStack{
                    Text("What time is it?")
                        .padding()
                        .foregroundColor(Color.white)
                        .font(.system(size: 30.0, weight: .bold))
                    HStack {
                        Button  {
                            result = "M"
                        } label: {
                            Text("Morning🌥")
                                .foregroundColor(Color.white)
                                .frame(width: 165, height: 100)
                                .background(Color(red: 0.0, green: 0.0, blue: 1.0, opacity: 1.0))
                                .cornerRadius(10)
                        }
                        Button  {
                            result = "E"
                        } label: {
                            Text("Evening☀️")
                                .foregroundColor(Color.white)
                                .frame(width: 165, height: 100)
                                .background(Color(red: 0.0, green: 0.0, blue: 1.0, opacity: 1.0))
                                .cornerRadius(10)
                    }
                }
                }
            case "E":
                VStack{
                    Text("Sweet or Savory?")
                        .padding()
                        .foregroundColor(Color.white)
                        .font(.system(size: 30.0, weight: .bold))
                    HStack {
                        Button  {
                            result = "EveningSweet"
                        } label: {
                            Text("Sweet🍦")
                        }
                        .foregroundColor(Color.white)
                        .frame(width: 165, height: 100)
                        .background(Color(red: 0.0, green: 0.0, blue: 1.0, opacity: 1.0))
                        .cornerRadius(10)
                        
                        Button  {
                            result = "EveningSavory"
                        } label: {
                            Text("Savory🧂")
                        }
                        .foregroundColor(Color.white)
                        .frame(width: 165, height: 100)
                        .background(Color(red: 0.0, green: 0.0, blue: 1.0, opacity: 1.0))
                        .cornerRadius(10)
                    
                }
            }

Solution

  • Using withAnimation{} to animate your event.

    Let's say you want to animate views after you click on Evening:

       Button  {
           withAnimation { //here
               result = "E" 
           }
       } label: {
         Text("Evening☀️")
             .foregroundColor(Color.white)
             .frame(width: 165, height: 100)
             .background(Color(red: 0.0, green: 0.0, blue: 1.0, opacity: 1.0))
             .cornerRadius(10)
        }
    

    This mean that all views that are related to this event of result = "E" shall be animated. The default transition of all animation is .opacity.

    After trying the first case, if you want to change transition type, use .transition()

    case "E":
        VStack {
    
        }.transition(.slide)
    

    You will see a different animation from the first time that you did not set transition equals to slide.

    I would recommend you try the first option without .slide first to see the difference.