使用 ZStack 将一个动画视图与另一个视图组合在一起



我正在开发一个 WatchOS 应用程序,该应用程序需要在等待任务完成时在另一个视图上显示动画。

我的方法是以下(连接视图(:

struct ConnectionView: View{
@EnvironmentObject var isConnected : Bool
var body: some View {
return VStack(alignment: .trailing){
ZStack{
ScrollView{
.....
} 
if(!isConnected){
ConnectionLoadingView()
}
}
}
}
}

对于 ConnectionLoadView:

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
}
}
}

真正的问题由两部分组成:

  1. 在应用程序启动后显示的第一个连接视图上,连接加载视图正确显示。在随后的运行中,ConnectionLoadView 具有奇怪的"淡入"效果,它在整个动画中更改了它的不透明度(如果我将视图的不透明度设置为 1、0 或介于两者之间的任何值都没有关系(。

  2. 如果我在连接加载视图中没有以下代码片段:

    if(!isConnected){
    animation = Animation.linear(duration: 4.0)
    }else{
    animation = Animation.linear(duration: 0)
    }
    

如果没有这个,ConnectionView将继续播放动画,但它从ZStack的前景移动到背景,在ScrollView后面,当它应该立即消失时?如果没有此代码段,则只有在任务完成之前动画已停止时,动画才会按预期消失。

有什么理由将 ConnectionLoadView 推送到 ZStack 的背景,而不是完全从视图中删除,当我明确声明它只应在且仅当!isConnected在 ConnectionView 中时才显示时?

我也不太清楚为什么初始 ConnectionView 的动画行为和后续的动画行为之间存在不透明度行为的差异。不透明度是否改变是线性动画的一部分?

谢谢!

你走错了动画。不应为此使用隐式动画。显式动画更适合。

隐式动画是使用 .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
}
}
}
}

最新更新