[英]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
要为 position和Text
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.