I set a view, when the state is different, it is in HStack or VStack. But when I set the animation, it does not meet my expectations. I want the view on the right to move up and down smoothly.(position1 moves smoothly to position2)
struct ContentView: View {
@State var show = false
var body: some View {
VStack {
VStack {
HStack {
Text("test spacer")
.contentShape(Rectangle())
.frame(minWidth: 0, maxWidth: .infinity)
.background(Color.red)
if !show {
Text("xxxxxx")
.background(Color.blue) // position1
}
}
if show {
HStack {
Spacer()
Text("xxxxxx")
.background(Color.blue) // position2
}
}
}
.background(Color.yellow)
.animation(.easeInOut(duration: 1), value: show)
Button("button") {
show.toggle()
}
}
.padding()
}
}
I used Sweeper's answer and used matchedGeometryEffect to solve the problem.
But I tried to change Text to Textfield and changed the timing of triggering the animation to focus. When the keyboard pops up, the animation does not execute smoothly.
How to make the elements in the view slide smoothly?
struct ContentView: View {
@State private var text = ""
@Namespace var ns
@FocusState private var isFocused: Bool
var body: some View {
ZStack {
Color.clear
.contentShape(Rectangle())
.onTapGesture {
isFocused = false
}
VStack {
HStack {
TextField("placeholder", text: $text, axis: .vertical)
.focused($isFocused)
.frame(minHeight: 28)
.background(Color.red)
if !isFocused {
Text("xxxxxx")
.background(Color.blue)
.matchedGeometryEffect(id: "xxxxxx", in: ns)
}
}
if isFocused {
HStack {
Spacer()
Text("xxxxxx")
.background(Color.blue)
.matchedGeometryEffect(id: "xxxxxx", in: ns)
}
}
}
.background(Color.yellow)
.animation(.easeInOut(duration: 1), value: isFocused)
}
.padding()
}
}
Use a matchedGeometryEffect
to "link" the two view's size and position together.
struct ContentView: View {
@State var show = false
@Namespace var ns
var body: some View {
VStack {
VStack {
HStack {
Text("test spacer")
.contentShape(Rectangle())
.frame(minWidth: 0, maxWidth: .infinity)
.background(Color.red)
if !show {
Text("xxxxxx")
.background(Color.blue)
// here
.matchedGeometryEffect(id: "xxxxxx", in: ns)
}
}
if show {
HStack {
Spacer()
Text("xxxxxx")
.background(Color.blue)
// and here
.matchedGeometryEffect(id: "xxxxxx", in: ns)
}
}
}
.background(Color.yellow)
.animation(.easeInOut(duration: 1), value: show)
Button("button") {
show.toggle()
}
}
.padding()
}
}