问题很简单:我到底如何获得Text
的动画?
struct ContentView: View {
@State var foozle: String = ""
var body: some View {
VStack() {
Spacer()
Text(self.foozle)
.frame(maxWidth: .infinity)
.transition(.opacity)
Button(action: {
withAnimation(.easeInOut(duration: 2)) {
self.foozle = "uuuuuuuuu"
}
}) { Text("ugh") }
Spacer()
}.frame(width: 320, height: 240)
}
}
问题:视图坚持执行一些愚蠢的动画,用新的文本替换文本,但用省略号将其截断,然后缓慢地沿宽度方向扩展,直到显示新的文本为止。
自然,这是不是不透明的动画。这不是一个框架宽度的问题,正如我在绘制边框时所证实的那样。
这只是SwiftUI中另一个愚蠢的错误,我需要处理,并祈祷有人修复它吗?
编辑:好的,所以感谢@ Mac3n,我得到了这个灵感,即使它有点难看,它也可以正常工作:
Text(self.foozle)
.frame(maxWidth: .infinity)
.opacity(op)
Button(action: {
withAnimation(.easeOut(duration: 0.3)) {
self.op = 0
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
self.foozle += "omo"
withAnimation(.easeIn(duration: 0.3)) {
self.op = 1
}
}
}
}) {
Text("ugh")
}
答案 0 :(得分:2)
如果要对不透明度进行动画处理,则需要更改文本元素上的不透明度值。
代码示例:
@State private var textValue: String = "Sample Data"
@State private var opacity: Double = 1
var body: some View {
VStack{
Text("\(textValue)")
.opacity(opacity)
Button("Next") {
withAnimation(.easeInOut(duration: 0.5), {
self.opacity = 0
})
self.textValue = "uuuuuuuuuuuuuuu"
withAnimation(.easeInOut(duration: 1), {
self.opacity = 1
})
}
}
}
答案 1 :(得分:2)
问题在于SwiftUI将“文本”视图视为同一视图。您可以在视图上使用.id()方法进行设置。在这种情况下,我只是将值设置为文本本身的哈希值,因此,如果更改文本,整个视图将被替换。
struct ContentView: View {
@State var foozle: String = ""
var body: some View {
VStack() {
Spacer()
Text(self.foozle)
.id(self.foozle.hashValue)
.frame(maxWidth: .infinity)
.transition(.opacity)
Button(action: {
withAnimation(.easeInOut(duration: 2)) {
self.foozle = "uuuuuuuuu"
}
}) { Text("ugh") }
Spacer()
}.frame(width: 320, height: 240)
}
}
答案 2 :(得分:1)
Transition
在视图出现/消失时起作用。在您的用例中,没有这样的工作流程。
以下是使用不透明动画隐藏/取消隐藏文本的可能方法的演示:
struct DemoTextOpacity: View {
var foozle: String = "uuuuuuuuu"
@State private var hidden = true
var body: some View {
VStack() {
Spacer()
Text(self.foozle)
.frame(maxWidth: .infinity)
.opacity(hidden ? 0 : 1)
Button(action: {
withAnimation(.easeInOut(duration: 2)) {
self.hidden.toggle()
}
}) { Text("ugh") }
Spacer()
}.frame(width: 320, height: 240)
}
}