动画渐变填充swiftUI

时间:2019-08-20 15:10:35

标签: swiftui

具有带有渐变填充的矩形,并尝试为颜色变化设置动画。

Using RNVectorIcons (6.6.0)

改变起点的动画效果很好;颜色的变化完全没有动画效果,只是“切换”

有任何提示吗?

2 个答案:

答案 0 :(得分:1)

因此,如果有人要为我当前的解决方案而苦恼,请在ZStack中具有两个渐变并为顶部的不透明动画设置

Example gif

这是一个粗糙的示例,可以肯定地写出更好的代码:

///helper extension to get some random Color
extension Color {
  static func random()->Color {
    let r = Double.random(in: 0 ... 1)
    let g = Double.random(in: 0 ... 1)
    let b = Double.random(in: 0 ... 1)
    return Color(red: r, green: g, blue: b)
  }
}

struct AnimatableGradientView: View {
  @State private var gradientA: [Color] = [.white, .red]
  @State private var gradientB: [Color] = [.white, .blue]

  @State private var firstPlane: Bool = true

  func setGradient(gradient: [Color]) {
    if firstPlane {
        gradientB = gradient
    }
    else {
        gradientA = gradient
    }
    firstPlane = !firstPlane
  }

  var body: some View {
    ZStack {
        Rectangle()
            .fill(LinearGradient(gradient: Gradient(colors: self.gradientA), startPoint: UnitPoint(x: 0, y: 0), endPoint: UnitPoint(x: 1, y: 1)))
        Rectangle()
            .fill(LinearGradient(gradient: Gradient(colors: self.gradientB), startPoint: UnitPoint(x: 0, y: 0), endPoint: UnitPoint(x: 1, y: 1)))
            .opacity(self.firstPlane ? 0 : 1)
        ///this button just demonstrates the solution
        Button(action:{
            withAnimation(.spring()) {
                self.setGradient(gradient: [Color.random(), Color.random()])
            }
        })
        {
            Text("Change gradient")
        }
    }
  }
}

更新:*最后,我探索了几种动画填充渐变的方法,并在此处进行了总结:https://izakpavel.github.io/development/2019/09/30/animating-gradients-swiftui.html *

答案 1 :(得分:0)

想分享另一个简单的选择。

两个矩形,每个矩形之间都带有动画纯色。 顶部的ZStack使用渐变蒙版将它们融合在一起。

    struct ContentView: View {
    
    @State var switchColor = false
   
    
    var body: some View {
        ZStack {
            RoundedRectangle(cornerRadius: 30)
                .fill(switchColor ? Color.purple : Color.green)
            ZStack {
                RoundedRectangle(cornerRadius: 30)
                    .fill(switchColor ? Color.pink : Color.yellow)
            }
            .mask(LinearGradient(gradient: Gradient(colors: [.clear,.black]), startPoint: .top, endPoint: .bottom))
            
        }
        .padding()
        .onTapGesture {
            withAnimation(.spring()) {
                switchColor.toggle()
            }
        }
        
    }
}