SwiftUI 视图以意想不到的路径动画
Posted
技术标签:
【中文标题】SwiftUI 视图以意想不到的路径动画【英文标题】:SwiftUI view animates at unexpected path 【发布时间】:2021-10-05 09:57:19 【问题描述】:我做了以下PulsatingView
:
struct PulsatingView: View
@State private var opacity = 0.7
@State private var scale: CGFloat = 0.5
var body: some View
VStack
ZStack
Circle()
.fill(Color.black.opacity(opacity))
.animation(.easeInOut(duration: 2).delay(1.5).repeatForever(autoreverses: false))
.frame(width: 7, height: 7)
.scaleEffect(scale)
.animation(.easeIn(duration: 2.5).delay(1).repeatForever(autoreverses: false))
Circle()
.fill(Color.black)
.frame(width: 7, height: 7)
.onAppear
opacity = 0
scale = 5
它产生以下结果:(点击查看动画;它是一个 .gif)
但是,当我将它添加到视图中时,例如在 VStack
中,会发生这种情况:(点击查看动画;它是一个 .gif)
我不知道为什么会发生这种情况或如何解决它。我已经尝试向其添加诸如.fixedSize(horizontal: true, vertical: true)
或.frame(width: 50, height: 50)
之类的修饰符,但这无济于事。
有人知道怎么回事吗?
【问题讨论】:
嗨@LinusGeffarth,我现在也有同样的问题。你找到解决办法了吗?我尝试了DispatchQueue.main.async
,但这没有用。还在挣扎。任何帮助将不胜感激,谢谢!
看来您已经找到了解决方案。对我来说,Asperi 的回答起到了作用(这就是我接受它的原因)。
是的,一切都很好,谢谢你回复我:)
【参考方案1】:
尝试使用带有连接值的动画,例如
Circle()
.fill(Color.black.opacity(opacity))
.animation(.easeInOut(duration: 2).delay(1.5).repeatForever(autoreverses: false), value: opacity) // << here !!
.frame(width: 7, height: 7)
.scaleEffect(scale)
.animation(.easeIn(duration: 2.5).delay(1).repeatForever(autoreverses: false), value: scale) // << here !!
重要提示:如果它是在NavigationView
启动的,那么动画状态应该被推迟激活。原因及调查详情见https://***.com/a/66643096/12299030。
【讨论】:
确实是NavigationView
!我试过你的代码,但问题仍然存在......
那么你需要像上面提供的第一个链接一样延迟动画开始。
啊哈!谢谢,第二个链接解决了我的问题。如果您在此处更新答案,我会将其标记为已接受。【参考方案2】:
这个问题与你的代码无关,因为 NavigationView 修复它我们应该使用DispatchQueue.main.async
我也想重构你的代码,希望对你有所帮助,你也可以尽可能避免硬编码值,例如你可以在视野之外应用框架:
struct ContentView: View
var body: some View
CircleView(lineWidth: 0.5, color: .red, scale: 5.0)
.frame(width: 7, height: 7)
struct CircleView: View
let lineWidth: CGFloat
let color: Color
let scale: CGFloat
@State private var startAnimation: Bool = Bool()
var body: some View
Circle()
.strokeBorder(style: .init(lineWidth: startAnimation ? .zero : lineWidth)).opacity(startAnimation ? .zero : 1.0)
.scaleEffect(startAnimation ? scale : 1.0)
.overlay( Circle() )
.foregroundColor(color)
.onAppear() DispatchQueue.main.async startAnimation.toggle()
.animation(.easeIn(duration: 2.5).delay(1).repeatForever(autoreverses: false), value: startAnimation)
【讨论】:
【参考方案3】:我终于设法在我自己的项目中找到了解决方案 - 我发现让动画视图在 NavigationView
中工作的唯一解决方案是将动画移动到 onAppear
调用中,如下所示:
Circle()
.fill(Color.black.opacity(opacity))
.onAppear
withAnimation(.easeInOut(duration: 2).repeatForever(autoreverses: false))
opacity = 0
希望这可以帮助其他人,如果他们被困在我最终遇到的同一问题上!
【讨论】:
以上是关于SwiftUI 视图以意想不到的路径动画的主要内容,如果未能解决你的问题,请参考以下文章