swift - 在 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))
}
}
解决方案
要激活动画,您需要切换一些值,因此动画师可以在两者之间进行动画处理。
这是固定代码。使用 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
修改器手动删除那些内部堆栈和布局)
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))
}
}
推荐阅读
- typescript - 如何在子接口的类型保护中使用父接口的类型保护?
- amazon-web-services - 无法从 AWS ECS 任务(awsvpc 网络模式)向 Twilio 发送请求
- java - 如何正确处理百里香?
- python - 如何通过python从xcel第一列读取数据
- asp.net-core - 如何将现有的 .NET Core Web 应用程序发布到 AWS Lambda
- c# - 在 ASP.net core 3.0 中更改身份登录 URL
- jquery - Bootstrap 4 不会运行 Javascript 依赖文件
- c++ - 关于从驱动器中删除文件的问题
- c++ - google mock - 如何模拟被测试类拥有的对象
- assembly - 如何将数组的元素存储在8086中的内存地址