如何使用SwiftUI在列表中创建脉动不透明度波?

如何使用SwiftUI在列表中创建脉动不透明度波?,swiftui,Swiftui,我已尝试使用以下代码 struct ContentView:View{ @状态变量show=false var body:一些观点{ 滚动视图{ LazyVStack(对齐:。中心,间距:0){ ForEach(1…100,id:\.self){index in 如果自我表现{ 文本(“占位符\(索引)”) .填充(24) .不透明度(1) .过渡( AnyTransition.opacity.animation( 动画 .easeOut(持续时间:0.6) .延迟(双倍(指数)*0.15) .

我已尝试使用以下代码

struct ContentView:View{
@状态变量show=false
var body:一些观点{
滚动视图{
LazyVStack(对齐:。中心,间距:0){
ForEach(1…100,id:\.self){index in
如果自我表现{
文本(“占位符\(索引)”)
.填充(24)
.不透明度(1)
.过渡(
AnyTransition.opacity.animation(
动画
.easeOut(持续时间:0.6)
.延迟(双倍(指数)*0.15)
.repeatForever(自动反转:true)
)
)
}
}
}
}奥纳佩尔先生{
self.show=true
}
}
}
这在第一次迭代中效果很好,但在下一次迭代中,延迟累积错误


想要的效果(左边第一个)。结果(右边最后一个)。

将其包装在UIView中似乎很有效,并提供了所需的效果

struct脉动视图:UIViewRepresentable{
var maxOpacity=0.7
var最小容量=0.2
风险值持续时间=0.5
var延迟=0.05
var-content:content
func makeUIView(上下文:context)->ViewContainer{
let view=ViewContainer(子级:内容)
返回视图
}
func updateUIView(ucontainer:ViewContainer,context:context){
让anim=CABasicAnimation()
anim.fromValue=最小产能
anim.toValue=最大不透明度
动画持续时间=持续时间
anim.autoreverses=真
anim.timingFunction=.init(名称:.easeInEaseOut)
anim.repeatCount=Float.greatestfinitemagnity
anim.timeOffset=-延迟
anim.keyPath=“不透明度”
container.child.rootView=内容
容器。图层。添加(动画,福克斯:“脉动”)
}
}
类ViewContainer:UIView{
var子级:UIHostingController
init(子:内容){
self.child=UIHostingController(rootView:child)
super.init(帧:.0)
addSubview(self.child.view)
}
必需初始化?(编码器:NSCoder){
fatalError(“初始化(编码者:)尚未实现”)
}
覆盖func布局子视图(){
super.layoutSubviews()
child.view.bounds=边界
child.view.center=CGPoint(x:bounds.width/2.0,y:bounds.height/2.0)
}
重写变量intrinsicContentSize:CGSize{
child.view.sizeThatFits(CGSize(宽度:Double.GreatestFiniteMagnite,高度:Double.GreatestFiniteMagnite))
}
}
结构ContentView:View{
var body:一些观点{
滚动视图{
LazyVStack(对齐:。中心,间距:0){
ForEach(1…1000,id:\.self){index in
脉动视图(
延迟:双倍(指数)*0.15,
内容:{
文本(“占位符\(索引)”)
.填充(24)
}()
)
}
}
}
}
}

但是,当与LazyVStack结合使用时,垂直放置会出现一些错误,这将是一个有效的解决方案

这个想法是用一个计时器来处理永远的重复

滚动也可以工作:

人们只需等待一点,因为延迟随着
双倍(索引)*0.15而线性增加

代码:

附加的 您可能希望使用
VStack
而不是
LazyVStack
。这将消除列表中元素不断增加的延迟,因为它们都会立即出现。我不知道你想要的效果是什么

import SwiftUI
import Combine

final class AnimationManager: ObservableObject {

    @Published var timer: AnyCancellable!
    @Published var show: Bool = false
    
    
    init() {
        timer = Timer.publish(every: 0.75, on: .main, in: .common)
            .autoconnect()
            .sink { _ in
                self.show.toggle()
            }
    }
}


struct ContentView: View {
    
    @StateObject private var animationManager = AnimationManager()
    
    
    var body: some View {
        ScrollView {
            LazyVStack(alignment: .center, spacing: 0) {
                ForEach(1...100, id: \.self) { index in
                    Text("Placeholder \(index)")
                        .padding(24)
                        .opacity(animationManager.show ? 1.0 : 0.1)
                        .animation(Animation.easeOut(duration: 0.6).delay(Double(index)*0.15))
                }
            }
        }
    }
}