UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

Animating transition between Linear Gradients

Forums > SwiftUI

Hi everyone

Here's my problem: I created a TabView with tabViewStyle(PageTabViewStyle()) and would like to have a different LinearGradient as background for each of the page. So far that wasn't too hard to build, however I'd like the LinearGradients to transition gracefully from one to another (I did it successfully for plain Color elements with the .animation(.default) modifier.

This is what I tried so far:

  1. With an array of gradients => The animation does not happen (the LinearGradient will change abrutly between pages)
struct ContentView: View {
    @State private var selected = 0   
    var blueBackground = LinearGradient(gradient: Gradient(colors: [Color.blue, Color.white]), startPoint: .topLeading, endPoint: .bottomLeading)

    var grayBackground = LinearGradient(gradient: Gradient(colors: [Color.gray, Color.white]), startPoint: .topLeading, endPoint: .bottomLeading)

    var gradients: [LinearGradient] {
        return [blueBackground, grayBackground, grayBackground]
    }

    var body: some View {
        ZStack {
            Rectangle().fill(gradients[selected]).edgesIgnoringSafeArea(.all)

            TabView(selection: $selected){
                Text("☀️").font(.title).tag(0)
                Text("🌦").font(.title).tag(1)
                Text("⛈").font(.title).foregroundColor(Color.white).tag(2)
            }.indexViewStyle(PageIndexViewStyle(backgroundDisplayMode: .always))
            .tabViewStyle(PageTabViewStyle())
        }.animation(.easeIn)
    }   
    }
  1. With a "conditional rendering" => The animation happens, but I get a weird "flash" when going from one page to another (see https://twitter.com/MaximeHeckel/status/1297380458163056640 for a video recording)
        struct ContentView: View {
          @State private var selected = 0

          var blueBackground = LinearGradient(gradient: Gradient(colors: [Color.blue, Color.white]), startPoint: .topLeading, endPoint: .bottomLeading)

          var grayBackground = LinearGradient(gradient: Gradient(colors: [Color.gray, Color.white]), startPoint: .topLeading, endPoint: .bottomLeading)

          var gradients: [LinearGradient] {
              return [blueBackground, grayBackground, grayBackground]
          }

          var body: some View {
              ZStack {
                  if selected == 0 {
                      Rectangle().fill(gradients[0]).edgesIgnoringSafeArea(.all)
                  } else {
                      Rectangle().fill(gradients[1]).edgesIgnoringSafeArea(.all)
                  }

                  TabView(selection: $selected){
                      Text("☀️").font(.title).tag(0)
                      Text("🌦").font(.title).tag(1)
                      Text("⛈").font(.title).foregroundColor(Color.white).tag(2)
                  }.indexViewStyle(PageIndexViewStyle(backgroundDisplayMode: .always))
                  .tabViewStyle(PageTabViewStyle())
              }.animation(.easeIn)
          }
       }

Currently on iOS 14 beta4 and developing on XCode beta 12 I'm pretty new to SwiftUI development, so maybe what I'm asking simply isn't possible or is a very complex problem.

Thank you in advance for your help!

2      

2      

TAKE YOUR SKILLS TO THE NEXT LEVEL If you like Hacking with Swift, you'll love Hacking with Swift+ – it's my premium service where you can learn advanced Swift and SwiftUI, functional programming, algorithms, and more. Plus it comes with stacks of benefits, including monthly live streams, downloadable projects, a 20% discount on all books, and free gifts!

Find out more

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.