Home > Net >  Frame transition animation works conditionally
Frame transition animation works conditionally

Time:07-26

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)
    }
}
  • Related