首页 > 解决方案 > 在 swiftUI 中创建星形动画时遇到问题

问题描述

我正在尝试使用模糊创建星星动画,但我的星星最终消失了,我不知道为什么。通过一些调试,我很确定这与我使用 onAppear 的方式有关。我只是想确保星星在​​屏幕上永远模糊和不模糊——但我总是希望星星可见。

谁能帮我解决这个问题(下面附上代码),任何设计技巧都将不胜感激哈哈。

struct ContentView: View {
    @State private var radius = 2
    private var opacity = 0.25
    var body: some View {
        ZStack {
            Color.black.edgesIgnoringSafeArea(.all)
            VStack  {
                ForEach(0..<8) {_ in
                HStack {
                    ForEach(0..<5) { _ in
                        Circle().fill(Color.white)
                        .frame(width: 3, height: 3)
                        .blur(radius: CGFloat(self.radius))
                        .animation(Animation.easeInOut(duration: 6).
                        repeatForever(autoreverses: true))
                        .padding(EdgeInsets(top: self.calculateRandom(), leading: 0,         
                       bottom: 0, trailing: self.calculateRandom()))
                        .onAppear() {
                            self.radius += 2
                                
                        }
                }
                }
            }
            }
            
            
        }
    }
    
    func calculateRandom() -> CGFloat {
        return CGFloat(Int.random(in: 30..<150))
    }
}

标签: swiftswiftui

解决方案


要激活动画,您需要切换一些值,因此动画师可以在两者之间进行动画处理。

这是固定代码。使用 Xcode 12 / iOS 14 测试。

演示

struct ContentView: View {
    @State private var run = false    // << here !!

    private var opacity = 0.25
    var body: some View {
        ZStack {
            Color.black.edgesIgnoringSafeArea(.all)
            VStack  {
                ForEach(0..<8) {_ in
                HStack {
                    ForEach(0..<5) { _ in
                        Circle().fill(Color.white)
                        .frame(width: 3, height: 3)
                        .blur(radius: run ? 4 : 2)     // << here !!
                        .animation(Animation.easeInOut(duration: 6).repeatForever(autoreverses: true))
                        .padding(EdgeInsets(top: self.calculateRandom(), leading: 0,
                       bottom: 0, trailing: self.calculateRandom()))
                        .onAppear() {
                            self.run = true     // << here !!
                        }
                }
                }
            }
            }


        }
    }

    func calculateRandom() -> CGFloat {
        return CGFloat(Int.random(in: 30..<150))
    }
}

更新:具有静态星形位置的变体(移动动画是由 V/H/Stacks 中的布局在添加新元素时引起的,因此为避免这种情况,需要在 ZStack 中使用.position修改器手动删除那些内部堆栈和布局)

演示2

struct BlurContentView: View {
    @State private var run = false
    
    var body: some View {
        ZStack {
            Color.black.edgesIgnoringSafeArea(.all)
            GeometryReader { gp in
                ForEach(0..<8) {_ in
                    ForEach(0..<5) { _ in
                        Circle().fill(Color.white)
                            .frame(width: 3, height: 3)
                            .position(x: calculateRandom(in: gp.size.width),
                                      y: calculateRandom(in: gp.size.height))
                            .animation(nil)     // << no animation for above modifiers
                            .blur(radius: run ? 4 : 2)
                        
                    }
                }
            }
            .animation(Animation.easeInOut(duration: 6)
                .repeatForever(autoreverses: true), value: run) // animate one value
            .onAppear() {
                self.run = true
            }
        }
    }
    
    func calculateRandom(in value: CGFloat) -> CGFloat {
        return CGFloat(Int.random(in: 10..<Int(value) - 10))
    }
}

推荐阅读