作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想在 SwiftUI 中创建一个星空背景 View ,其星星使用 Double.random()
随机定位,但在父 View 重新加载其 时不会重新初始化它们并移动它们>var 正文
。
struct ContentView: View {
@State private var showButton = true
var body: some View {
ZStack {
BackgroundView()
if showButton {
Button("Tap me"){
self.showButton = false
}
}
}
}
}
我这样定义我的背景 View 。
struct BackgroundView: View {
var body: some View {
ZStack {
GeometryReader { geometry in
Color.black
ForEach(0..<self.getStarAmount(using: geometry), id: \.self){ _ in
Star(using: geometry)
}
LinearGradient(gradient: Gradient(colors: [.purple, .clear]), startPoint: .bottom, endPoint: .top)
.opacity(0.7)
}
}
}
func getStarAmount(using geometry: GeometryProxy) -> Int {
return Int(geometry.size.width*geometry.size.height/100)
}
}
星
定义为
struct Star: View {
let pos: CGPoint
@State private var opacity = Double.random(in: 0.05..<0.4)
init(using geometry: GeometryProxy) {
self.pos = CGPoint(x: Double.random(in: 0..<Double(geometry.size.width)), y: Double.random(in: 0..<Double(geometry.size.height)))
}
var body: some View {
Circle()
.foregroundColor(.white)
.frame(width: 2, height: 2)
.scaleEffect(CGFloat(Double.random(in: 0.25...1)))
.position(pos)
.opacity(self.opacity)
.onAppear(){
withAnimation(Animation.linear(duration: 2).delay(Double.random(in: 0..<6)).repeatForever()){
self.opacity = self.opacity+0.5
}
}
}
}
正如人们所看到的,Star
的动画(以创建“随机”闪烁效果)及其位置都严重依赖于随机值。然而,当 BackgroundView
(本例中为 ContentView
)的父 View 重绘时,所有 Star
都会重新初始化,它们的位置值会发生变化,并且在屏幕上移动。如何最好地防止这种情况发生?
我尝试了多种方法来防止位置被重新初始化。我可以创建一个struct StarCollection
作为BackgroundView
的static let
,但这相当麻烦。让 View 依赖于随机值(位置)的最佳方法是什么,仅确定这些位置一次?
此外,渲染速度相当慢。我尝试在 ForEach
上调用 .drawingGroup()
,但这似乎会干扰动画的不透明度插值。有没有可行的方法来加速具有许多 Circle()
元素的 View 的创建/重新渲染?
最佳答案
由于onAppear中的动画设置过于复杂而导致速度缓慢,您只需要改变self.opacity
状态即可启动动画,因此请将动画移出并直接添加到形状中。
Circle()
.foregroundColor(.white)
.frame(width: 2, height: 2)
.scaleEffect(CGFloat(Double.random(in: 0.25...1)))
.position(pos)
.opacity(self.opacity)
.animation(Animation.linear(duration: 0.2).delay(Double.random(in: 0..<6)).repeatForever())
.onAppear(){
// withAnimation{ //(Animation.linear(duration: 2).delay(Double.random(in: 0..<6)).repeatForever()){
self.opacity = self.opacity+0.5
// }
}
关于SwiftUI 查看结构而无需重新加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58609963/
我是一名优秀的程序员,十分优秀!