ios - 使用 ZStack 将动画视图与另一个视图组合
问题描述
我正在开发一个 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 将继续播放动画,但将它从 ZStack 的前景移到 ScrollView 后面的背景,什么时候它应该立即消失?如果没有此代码片段,动画只会在动画在任务完成之前停止时才会消失。
当我明确指出仅当且仅当在 ConnectionView 中时才应显示 ConnectionLoadView 时,是否有任何理由将 ConnectionLoadView 推送到 ZStack 的背景而不是完全从视图中删除!isConnected
?
我也不太明白为什么初始 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
}
}
}
}
推荐阅读
- javascript - AngularFirestore - 动态更新查询
- angular - 避免 Angular Material Autocomplete 为空时显示 mat-options
- php - 在单击 php 文件的注册按钮时创建 s3 存储桶
- arrays - R数据帧到3维数组
- angular - Angular 如何在动态组件中使用@decorators?
- node.js - 无法在 PhantomJS 中接收 POST 请求数据
- android - 将房间持久性库与 MPAndroidChart 集成?
- python - python,将数据列表转换为数据框
- java - Intellij Idea 中的 Github 克隆
- python - 为什么我不能在 BeautifulSoup 上应用功能