I am trying to make child view which contains string array moves back and forth with animation as button on parent view is toggled. However, child view just show up and disappeared without any animation at all.
struct ParentView: View {
@State isToggle: Bool
var body: some View {
ChildView(isToggle: isToggle)
.onTabGesture {
withAnimation {
isToggle.toggle()
}
}
}
}
struct ChildView: View {
let values = [one, two, three, four]
var isToggle: Bool
var body: some View {
HStack {
ForEach(values) { value in
Text("\(value)")
.frame(width: UIScreen.main.bounds.width / 3)
}
}
.frame(width: UIScreen.main.bounds.width, alignment: isToggle ? .trailing : .leading)
}
I changed code(stored property to viewmodel) as below. and It works as expected.
class ViewModel: ObservableObject {
@Published var values = [one, two, three, four]
}
struct ParentView: View {
@State isToggle: Bool
var body: some View {
ChildView(isToggle: isToggle)
.onTabGesture {
withAnimation {
isToggle.toggle()
}
}
}
}
struct ChildView: View {
@EnvironmentObject private vm: ViewModel
var isToggle: Bool
var body: some View {
HStack {
ForEach(values) { vm.value in
Text("\(value)")
.frame(width: UIScreen.main.bounds.width / 3)
}
}
.frame(width: UIScreen.main.bounds.width, alignment: isToggle ? .trailing : .leading)
}
I thought that toggling state redraws view only when with stored property. But, child view with viewmodel is still redrawn when toggle state changes. Data itself not changed at all. Please kindly let me know why this is happening.
CodePudding user response:
there are some minor typos in your first code. If I correct them the code runs, and the animation works:
struct ContentView: View {
@State private var isToggle: Bool = false
var body: some View {
ChildView(isToggle: isToggle)
.onTapGesture {
withAnimation {
isToggle.toggle()
}
}
}
}
struct ChildView: View {
let values = ["one", "two", "three", "four"]
var isToggle: Bool
var body: some View {
HStack {
ForEach(values, id: \.self) { value in
Text("\(value)")
.frame(width: UIScreen.main.bounds.width / 3)
}
}
.frame(width: UIScreen.main.bounds.width, alignment: isToggle ? .trailing : .leading)
}
}