在 SwiftUI 中,我有以下视图作为骨架加载器。我正在尝试让模糊的叠加层从左侧平滑地进入并从右侧平滑地呈现动画。
这是以下代码产生的结果(在轻量模式下)。正如您所看到的,动画的开始和结束并没有将叠加层平滑地动画化,而是在没有动画的情况下插入它,然后在大部分情况下对其进行动画处理,然后在没有动画的情况下将其删除。
struct SkeletonLoader: View {
@State private var isAnimating: Bool = false
let radius: CGFloat = 50
var body: some View {
GeometryReader { geo in
Rectangle()
.fill(Color(CGColor(gray: 0, alpha: 0.15)))
.overlay(
Rectangle()
.fill(Color(CGColor(gray: 0, alpha: 0.6)))
.frame(width: geo.size.width, height: 1000)
.blur(radius: radius)
.position(x: isAnimating ? geo.size.width + 180 + radius : -200 - radius)
)
.onAppear {
withAnimation(.easeIn(duration: 6.5).repeatForever(autoreverses: false)) {
isAnimating.toggle()
}
}
}
.clipped()
}
}
出于某种原因,删除 .clipped
可以修复平滑的动画问题,但我需要剪辑视图,以便模糊不会超出我的视图。我怀疑这是 SwiftUI 的问题,如果它的
position
不在屏幕上,即使仍然有一些模糊需要制作动画。我怎样才能让这个动画从开始到结束顺利进行?
作为解决方法,您可以使用
Material
叠加来提供模糊效果:
GeometryReader { geo in
Color(CGColor(gray: 0, alpha: 0.15))
.overlay(
Color.black
.frame(width: geo.size.width, height: 1000)
.position(x: isAnimating ? geo.size.width + 180 + radius : -200 - radius)
)
.overlay {
Rectangle()
.fill(.regularMaterial)
}
.onAppear {
withAnimation(.easeIn(duration: 6.5).repeatForever(autoreverses: false)) {
isAnimating.toggle()
}
}
}
.clipped()
Rectangle()
.fill(Color(CGColor(gray: 0, alpha: 0.15)))
.overlay(
Rectangle()
.fill(Color(CGColor(gray: 0, alpha: 0.6)))
...
)
.compositingGroup()