我正在开发一个WatchOS应用程序,该应用程序需要在等待任务完成时在另一个视图之上显示动画。
我的方法如下(ConnectionView):
struct ConnectionView: View{
@EnvironmentObject var isConnected : Bool
var body: some View {
return VStack(alignment: .trailing){
ZStack{
ScrollView{
.....
}
if(!isConnected){
ConnectionLoadingView()
}
}
}
}
}
对于ConnectionLoadingView:
struct ConnectionLoadView: View {
@State var isSpinning = false
@EnvironmentObject var isConnected : Bool
var body: some View {
var animation : Animation
///This is needed in order to make the animation stop when isConnected is true
if(!isConnected){
animation = Animation.linear(duration: 4.0)
}else{
animation = Animation.linear(duration: 0)
}
return Image(systemName: "arrowtriangle.left.fill")
.resizable()
.frame(width: 100, height: 100)
.rotationEffect(.degrees(isSpinning ? 360 : 0))
.animation(animation)
.foregroundColor(.green)
.onAppear(){
self.isSpinning = true
}
.onDisappear(){
self.isSpinning = false
}
}
}
真正的问题包括两部分:
在启动应用程序后显示的第一个ConnectionView上,可以正确显示ConnectionLoadView。在随后的运行中,ConnectionLoadView具有怪异的“淡入”效果,该效果会在整个动画中更改其不透明度(将视图的不透明度设置为1、0或之间的任何值都没有关系)。
如果ConnectionLoadView中没有以下代码段:
if(!isConnected){
animation = Animation.linear(duration: 4.0)
}else{
animation = Animation.linear(duration: 0)
}
否则,ConnectionView将继续播放动画,但是将其从ScrollView后面的ZStack的前景移动到ZStack的前景时,何时应该立即消失?没有此代码段,则动画将仅在动画在任务完成之前停止时才消失。
当我明确指出仅当!isConnected
仅在ConnectionView中显示时,将ConnectionLoadView推送到ZStack的背景而不是从视图中完全删除吗? / p>
我也不太清楚为什么初始ConnectionView的动画行为与后续ConnectionView的动画行为在不透明度行为方面存在差异。线性动画的不透明度改变了吗?
谢谢!
答案 0 :(得分:2)
您正在接近动画错误。您不应该为此使用隐式动画。显式动画更适合。
隐式动画是您使用.animation()应用的动画。这会影响在视图上更改的所有可设置动画的参数。
显式动画是您用withAnimation { ... }
触发的动画。只有受闭包内部修改的变量影响的参数才会生效。其余的不会。
新代码如下:
import SwiftUI
class Model: ObservableObject {
@Published var isConnected = false
}
struct Progress: View{
@EnvironmentObject var model: Model
var body: some View {
return VStack(alignment: .trailing){
ZStack{
ScrollView{
ForEach(0..<3) { idx in
Text("Some line of text in row # \(idx)")
}
Button("connect") {
self.model.isConnected = true
}
Button("disconect") {
self.model.isConnected = false
}
}
if !self.model.isConnected {
ConnectionLoadView()
}
}
}
}
}
struct ConnectionLoadView: View {
@State var isSpinning = false
@EnvironmentObject var model: Model
var body: some View {
return Image(systemName: "arrowtriangle.left.fill")
.resizable()
.frame(width: 100, height: 100)
.rotationEffect(.degrees(isSpinning ? 360 : 0))
.foregroundColor(.green)
.onAppear(){
withAnimation(Animation.linear(duration: 4.0).repeatForever(autoreverses: false)) {
self.isSpinning = true
}
}
}
}