不透明度的 SwiftUI 文本动画不起作用
SwiftUI Text animation on opacity does not work
问题很简单:我到底怎样才能让 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")
}
如果您想在不透明度上设置动画,您需要更改文本元素的不透明度值。
代码示例:
@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
})
}
}
}
Transition
在视图 appeared/disappeared 时有效。在您的用例中没有这样的工作流程。
这里是 hide/unhide 带有不透明度动画的文本的可能方法演示:
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)
}
}
问题是 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)
}
}
问题很简单:我到底怎样才能让 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")
}
如果您想在不透明度上设置动画,您需要更改文本元素的不透明度值。
代码示例:
@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
})
}
}
}
Transition
在视图 appeared/disappeared 时有效。在您的用例中没有这样的工作流程。
这里是 hide/unhide 带有不透明度动画的文本的可能方法演示:
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)
}
}
问题是 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)
}
}