[英]How to move text and change it's value at the same time in SwiftUI?
For example, this is what happening right now例如,这就是现在发生的事情
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()
}
The code above leads to this in Live Preview: click there上面的代码在实时预览中导致了这一点:点击那里
This happens if text doesn't change its value ( I need this behaviour with changing ): click there如果文本没有改变它的值(我需要这种改变的行为),就会发生这种情况:点击那里
One of the simplest way to achieve this animation is to embed two Text
inside a ZStack
and modify their opacity, and modify the ZStack's offset rather than the individual Texts.实现此 animation 的最简单方法之一是在ZStack
中嵌入两个Text
并修改它们的不透明度,并修改 ZStack 的偏移量而不是单个文本。 in this way both the offset and the change between two texts will get animated.通过这种方式,两个文本之间的偏移量和变化都将被动画化。 here is my code:这是我的代码:
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")
}
}
}
edit: I forgot to animate the text change编辑:我忘了为文本更改设置动画
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()
}
}
}
}
}
A good way to animate such change is to animate the offset value rather than toggle a boolean:动画这种变化的一个好方法是动画偏移值而不是切换 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
}
}
}
}
}
or by using a boolean value:或者使用 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()
}
}
}
}
}
Note the important withAnimation
that indicates to SwiftUI that you want to animate the changes made in the block.请注意重要的withAnimation
,它向 SwiftUI 指示您要为块中所做的更改设置动画。 You can find the documentation here您可以在此处找到文档
The .animation(...)
is optional and used if you want to change the behavior of the animation, such as using a spring, changing the speed, adding a delay etc... If you don't specify one, SwiftUI will use a default value. .animation(...)
是可选的,如果您想更改 animation 的行为,例如使用 spring、更改速度、添加延迟等...如果您不指定,SwiftUI 将使用默认值。 In a similar fashion, if you don't want a view to animate, you can use add the .animation(nil)
modifier to prevent SwiftUI from animating said view.以类似的方式,如果您不想让视图动画化,您可以使用添加.animation(nil)
修饰符来防止 SwiftUI 为所述视图设置动画。
Both solutions provided result in the following behavior: https://imgur.com/sOOsFJ0提供的两种解决方案都会导致以下行为: https://imgur.com/sOOsFJ0
To animate the position and the content of the Text
label, you can use matchedGeometryEffect
, as follows:要为 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.