繁体   English   中英

如何在 SwiftUI 中同时移动文本并更改其值?

[英]How to move text and change it's value at the same time in SwiftUI?

例如,这就是现在发生的事情

struct ContentView: View {
    @State var titleLable = "This is basic text"
    @State var isTextAnimated: Bool = false
    var body: some View {
        VStack {
            Text(titleLable)
                .offset(y: isTextAnimated ? 300 : 0)
                .animation(.linear)
            Button {
                isTextAnimated.toggle()
                if isTextAnimated {
                    titleLable = "New text appeared"
                } else {
                    titleLable = "This is basic text"
                }
            } label: {
                Text("Press")
            }
        }
        .padding()
    }

上面的代码在实时预览中导致了这一点:点击那里

如果文本没有改变它的值(我需要这种改变的行为),就会发生这种情况:点击那里

实现此 animation 的最简单方法之一是在ZStack中嵌入两个Text并修改它们的不透明度,并修改 ZStack 的偏移量而不是单个文本。 通过这种方式,两个文本之间的偏移量和变化都将被动画化。 这是我的代码:

struct HomeScreen: View {
    @State var isTextAnimated: Bool = false
    
    var body: some View {
        ZStack{
            Text("Hello")
                .opacity(isTextAnimated ? 1 : 0)
            Text("World")
                .opacity(isTextAnimated ? 0 : 1)
        }
        .offset(y: isTextAnimated ? 150 : 0)
        
        
        Button(action: {withAnimation{isTextAnimated.toggle()}}){
            Text("Press")
        }
        
    }
}

编辑:我忘了为文本更改设置动画

struct AnimationsView: View {
    @State private var buttonWasToggled = false
    @Namespace private var titleAnimationNamespace

    var body: some View {
        VStack {
            if !buttonWasToggled {
                Text("This is some text")
                    .matchedGeometryEffect(id: "text", in: titleAnimationNamespace)
                    .transition(.opacity)
            } else {
                Text("Another text")
                    .matchedGeometryEffect(id: "text", in: titleAnimationNamespace)
                    .transition(.opacity)
                    .offset(y: 300)
            }

            Button("Press me") {
                withAnimation {
                    buttonWasToggled.toggle()
                }
            }
        }
    }
}

动画这种变化的一个好方法是动画偏移值而不是切换 boolean:

struct AnimationsView: View {
    @State private var title = "This is basic text"
    @State private var offset: CGFloat = 0

    var body: some View {
        VStack {
            Text("Some text")
                .offset(y: offset)

            Button("Press me") {
                withAnimation {
                    // If we already have an offset, jump back to the previous position
                    offset = offset == 0 ? 300 : 0
                }
            }
        }
    }
}

或者使用 boolean 值:

struct AnimationsView: View {
    @State private var title = "This is basic text"
    @State private var animated = false

    var body: some View {
        VStack {
            Text("Some text")
                .offset(y: animated ? 300 : 0)

            Button("Press me") {
                withAnimation {
                    animated.toggle()
                }
            }
        }
    }
}

请注意重要的withAnimation ,它向 SwiftUI 指示您要为块中所做的更改设置动画。 您可以在此处找到文档

.animation(...)是可选的,如果您想更改 animation 的行为,例如使用 spring、更改速度、添加延迟等...如果您不指定,SwiftUI 将使用默认值。 以类似的方式,如果您不想让视图动画化,您可以使用添加.animation(nil)修饰符来防止 SwiftUI 为所述视图设置动画。

提供的两种解决方案都会导致以下行为: https://imgur.com/sOOsFJ0

要为 positionText label 的内容设置动画,您可以使用matchedGeometryEffect ,如下所示:

struct ContentView: View {
    @State var isTextAnimated: Bool = false
    @Namespace var namespace
    
    var body: some View {
        VStack {
            if isTextAnimated {
                Text("New text appeared")
                    .matchedGeometryEffect(id: "title", in: namespace)
                    .offset(y: 300)
            } else {
                Text("This is basic text")
                    .matchedGeometryEffect(id: "title", in: namespace)
            }
            Button {
                withAnimation {
                    isTextAnimated.toggle()
                }
            } label: {
                Text("Press")
            }
        }
        .padding()
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM