我正在尝试使用模糊效果创建星星动画,但是星星最终消失了,我不知道为什么。 通过一点调试,我很确定这与我使用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))
}
}
答案 0 :(得分:1)
要激活动画,您需要切换一些值,因此动画师的动画范围必须介于两者之间。
这里是固定代码。在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))
}
}
更新:具有静态 star 位置的变体(运动动画是由添加新元素后在V / H / Stack中的布局引起的,因此需要避免这种情况使用.position
修饰符在ZStack中手动删除这些内部堆栈和布局)
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))
}
}