gpt4 book ai didi

SwiftUI 查看结构而无需重新加载

转载 作者:行者123 更新时间:2023-12-01 22:43:37 25 4
gpt4 key购买 nike

我想在 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作为BackgroundViewstatic 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com