不透明度的SwiftUI文字动画不起作用

时间:2020-02-11 23:19:31

标签: swift macos cocoa swiftui

问题很简单:我到底如何获得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")
}

3 个答案:

答案 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在视图出现/消失时起作用。在您的用例中,没有这样的工作流程。

以下是使用不透明动画隐藏/取消隐藏文本的可能方法的演示:

enter image description here

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