众所周知,一旦状态值发生改变(使用了动画修改),相关的View就会触发过渡动画。
异常动画现象
把动画时长调慢一点可以看到:
这个Button
在动画过程中,会出现两个Text
!
其中Button
的代码如下:
Button {
withAnimation(.easeInOut(duration: 0.5)) {
name = name == .none ? "迪丽热巴" : .none
}
} label: {
Text(name == .none ? "这是谁?" : "返回")
.font(.title2)
.frame(width: 100)
}
.buttonStyle(.borderedProminent)
.buttonBorderShape(.capsule)
.controlSize(.large)
废话不多说,直接解释:这是因为Button
中的Text
“原本”的变形动画被替换成默认的转场动画了!
至于为什么会被替换了呢?首先简单介绍一下SwiftUI
的过渡动画类型:
转场动画
两个不同的View
发生变化时,会触发转场动画。
会有变化前后的两个View
做转场动画(默认淡入淡出):
- 变化前的
View
保持在初始位置,默认淡出(alpha 1 –> 0) - 变化后的
View
直接在最终位置,默认淡入(alpha 0 –> 1)
触发场景:
@ViewBuilder
中结构位置不一样的View
:例如if {} else {}
等控制语句返回不同的View
@ViewBuilder
中结构位置一样但id
不一样的View
变形动画
同一个的View
发生变化时(初始值或者其Modifier
用到的状态值发生了变化),只要能通过计算得出的数值(位置、大小、角度等),就能触发变形动画。
但是,如果SwiftUI
不知道怎么做变形动画,就会用默认的转场动画(淡入淡出)来代替!
很明显,文本变形是无法通过计算得出的。
解决方案
由于SwiftUI
不会做文本变形,因此Button
中的Text
“原本”的变形动画被替换成默认的转场动画,所以才会有两个Text
淡入淡出。
虽说做不了文本变形,但除文本以外的变形动画(位置)SwiftUI
还是能做的,只是系统默认会把其他能算的变形动画一起忽略掉了!
如何解决?只要告诉SwiftUI
不要忽略其他的变形动画即可:
Button {
withAnimation(.easeInOut(duration: 0.5)) {
name = name == .none ? "迪丽热巴" : .none
}
} label: {
Text(name == .none ? "这是谁?" : "返回")
.font(.title2)
.frame(width: 100)
// 如果不想要淡入淡出效果就加上这句(PS:要在transformEffect前面移除)
//.animation(.none, value: name)
.transformEffect(.identity) // 要加上变形效果!
}
.buttonStyle(.borderedProminent)
.buttonBorderShape(.capsule)
.controlSize(.large)
最终效果:
其他
@ViewBuilder
中结构位置的注意点:
var body: some View {
// 这种触发的是转场动画
if name == .none {
Color.red
} else {
Color.yellow
}
// 这种触发的是变形动画
name == .none ? Color.red : Color.yellow
// 变形动画 -转-> 转场动画:只要id不一样
Text("Custom Transition")
.font(.largeTitle)
.bold()
.id(name)
// transition:自定义转场效果,在转场动画中才有效
.transition(.scale)
}
© 版权声明
文章版权归作者所有,未经允许请勿转载,侵权请联系 admin@trc20.tw 删除。
THE END