【问题标题】:SwiftUI - Pulsating Animation & Change ColourSwiftUI - 脉动动画和改变颜色
【发布时间】:2020-02-09 17:12:01
【问题描述】:

我正在尝试根据某物的状态更改动画的颜色。颜色变化有效,但它会用它为以前的(橙色)颜色设置动画。我不太明白为什么两种颜色都会显示。有什么想法吗?

struct PulsatingView: View {

    var state = 1

    func colourToShow() -> Color {
        switch state {
        case 0:
            return Color.red
        case 1:
            return Color.orange
        case 2:
            return Color.green
        default:
            return Color.orange
        }
    }

    @State var animate = false
    var body: some View {
        VStack {
            ZStack {
                Circle().fill(colourToShow().opacity(0.25)).frame(width: 40, height: 40).scaleEffect(self.animate ? 1 : 0)
                Circle().fill(colourToShow().opacity(0.35)).frame(width: 30, height: 30).scaleEffect(self.animate ? 1 : 0)
                Circle().fill(colourToShow().opacity(0.45)).frame(width: 15, height: 15).scaleEffect(self.animate ? 1 : 0)
                Circle().fill(colourToShow()).frame(width: 6.25, height: 6.25)
            }
            .onAppear { self.animate.toggle() }
            .animation(Animation.easeInOut(duration: 1.5).repeatForever(autoreverses: true))
        }
    }
}

【问题讨论】:

    标签: animation colors swiftui


    【解决方案1】:

    您更改了颜色,但设置的动画视图永远没有改变 - 它保持原样并按照指定的方式继续 - 永远。所以需要重新设置动画。

    请在下面找到完整的模块演示代码(使用 Xcode 11.2 / iOS 13.2 测试)。这个想法是使用ObservableObject 视图模型,因为它允许刷新视图并在接收时执行一些操作。因此接收颜色变化可以重置和查看颜色和动画。

    import SwiftUI
    import Combine
    
    class PulsatingViewModel: ObservableObject {
        @Published var colorIndex = 1
    }
    
    struct PulsatingView: View {
    
        @ObservedObject var viewModel: PulsatingViewModel
    
        func colourToShow() -> Color {
            switch viewModel.colorIndex {
            case 0:
                return Color.red
            case 1:
                return Color.orange
            case 2:
                return Color.green
            default:
                return Color.orange
            }
        }
    
        @State var animate = false
        var body: some View {
            VStack {
                ZStack {
                    Circle().fill(colourToShow().opacity(0.25)).frame(width: 40, height: 40).scaleEffect(self.animate ? 1 : 0)
                    Circle().fill(colourToShow().opacity(0.35)).frame(width: 30, height: 30).scaleEffect(self.animate ? 1 : 0)
                    Circle().fill(colourToShow().opacity(0.45)).frame(width: 15, height: 15).scaleEffect(self.animate ? 1 : 0)
                    Circle().fill(colourToShow()).frame(width: 6.25, height: 6.25)
                }
                .onAppear { self.animate = true }
                .animation(animate ? Animation.easeInOut(duration: 1.5).repeatForever(autoreverses: true) : .default)
                .onReceive(viewModel.$colorIndex) { _ in
                    self.animate = false
                    DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
                        self.animate = true
                    }
                }
            }
        }
    }
    
    struct TestPulseColorView: View {
        private var model = PulsatingViewModel()
        var body: some View {
            VStack {
                Spacer()
                PulsatingView(viewModel: model)
                Spacer()
                Button("Toggle") { self.model.colorIndex = Int.random(in: 0...2) }
            }
        }
    }
    
    struct TestPulseColorView_Previews: PreviewProvider {
        static var previews: some View {
            TestPulseColorView()
        }
    }
    

    【讨论】:

    • Asperi,每次看到你的回答,我都会学到一些新东西。
    猜你喜欢
    • 2015-03-20
    • 2020-01-09
    • 2011-06-29
    • 2017-11-30
    • 2011-07-19
    • 1970-01-01
    • 1970-01-01
    • 2021-12-17
    • 2012-11-18
    相关资源
    最近更新 更多