swift - 如何保持动画在 TabView 视图变化上运行?
问题描述
我最近发现,当一个动画永远运行并且View
通过 切换时TabView
,动画状态会丢失。虽然这是预期的行为,但我想了解在 TabView 视图更改后,是否有办法在返回动画视图时保持动画运行?
这是一个简单的示例,展示了 SwiftUI 中的行为:
import SwiftUI
class MyState: ObservableObject {
@Published var animate: Bool = false
}
struct ContentView: View {
var body: some View {
TabView {
AnimationView()
.tabItem {
Image(systemName: "eye")
}
Text("Some View")
.tabItem {
Image(systemName: "play")
}
}
}
}
struct AnimationView: View {
@EnvironmentObject var myState: MyState
var body: some View {
VStack {
Text(self.myState.animate ? "Animation running" : "Animation stopped")
.padding()
ZStack {
Circle()
.stroke(style: StrokeStyle(lineWidth: 12.0))
.foregroundColor(Color.black)
.opacity(0.3)
Circle()
.trim(
from: 0,
to: self.myState.animate ? 1.0 : 0.0
)
.stroke(
style: StrokeStyle(lineWidth: 12.0, lineCap: .round, lineJoin: .round)
)
.animation(
Animation
.linear(duration: self.myState.animate ? 1.0 : 0.0)
.repeatForever(autoreverses: false)
)
}.frame(width: 200, height: 200)
Button(action: {
self.myState.animate.toggle()
}) {
Text("Toggle animation")
.padding()
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
.environmentObject(MyState())
}
}
您可以在下面看到行为:
我期望控制的是回到动画运行的视图并查看它在当前时间的状态 - 这是,想象动画在切换视图时循环并返回视图找到它在“运行时间”或“实时”的正确点。
Obs:状态在视图中处理MyState
,EnvironmentObject
它不是本地(@State)
解决方案
所以我添加了一个额外的参数来MyState
存储用户在选项卡之间切换时的当前动画状态。以下是更新后的代码。我还在代码中添加了注释以便更好地理解。
class MyState: ObservableObject {
@Published var animate: Bool = false
var isAnimationActive = false // Store animate status when user switches between tabs
}
struct AnimationView: View {
@EnvironmentObject var myState: MyState
var body: some View {
VStack {
Text(self.myState.animate ? "Animation running" : "Animation stopped")
.padding()
ZStack {
Circle()
.stroke(style: StrokeStyle(lineWidth: 12.0))
.foregroundColor(Color.black)
.opacity(0.3)
Circle()
.trim(
from: 0,
to: self.myState.animate ? 1.0 : 0.0
)
.stroke(
style: StrokeStyle(lineWidth: 12.0, lineCap: .round, lineJoin: .round)
)
.animation(
Animation
.linear(duration: self.myState.animate ? 1.0 : 0.0)
.repeatForever(autoreverses: false)
)
}.frame(width: 200, height: 200)
Button(action: {
self.myState.animate.toggle()
}) {
Text("Toggle animation")
.padding()
}
}
.onAppear(perform: {
if self.myState.isAnimationActive {
/*switching the animation inside withAnimation block is important*/
withAnimation {
self.myState.animate = true
}
}
})
.onDisappear {
self.myState.isAnimationActive = self.myState.animate
/*The property needs to be set to false as SwiftUI compare the
views before re-rendering them*/
self.myState.animate = false
}
}
}
推荐阅读
- javascript - TypeError:无法读取未定义 vueJS 的属性“_wrapper”
- google-sheets - 对 Google 表格查询()公式中的特定列进行重复数据删除
- internet-explorer - .NET WebBrowser 控件不显示网页图形
- solr - 按两组数据组合的分数排序结果 (Solr)
- python-3.x - 删除表中的所有记录后,Django转储数据变慢
- python - 使用另一个数据框替换数据框值,没有索引匹配
- angular - 已解决 - 从指令中的组件获取属性 id
- python - 如何解决 pyhon 错误:分配前引用的局部变量“x”
- frameworks - Apple Silicon / M1 的 LAME.framework
- java - 事件溯源 - 复杂的聚合设计