Dimillian / SwiftUIFlux

A very naive implementation of Redux using Combine BindableObject to serve as an example
Apache License 2.0
650 stars 65 forks source link

Q: ConnectedView – animations/transitions on props changes #7

Open skinandbones opened 4 years ago

skinandbones commented 4 years ago

I'm really loving SwiftUIFlux and the direction things are going with ConnectedView. Great job!

One question I've run into is how to handle animations when props change. Here's a very contrived example (leaving out some bits for brevity) ...

struct SimpleExample: ConnectedView {
  struct Props {
    let isVisible: Bool
  }

  func map(state: AppState, dispatch: @escaping DispatchFunction) -> Props {
    return Props(
      isVisible: state.isVisible
    )
  }

  func body(props: Props) -> some View {
    VStack {
      Text("A simple example")

      if props.isVisible {
        Text("I'm visible!").transition(.slide).animation(.easeInOut)
      }
    }
  }
}

This all works except for the animation/transition.

Generally we'd just handle this stuff with @State .... bindings and be done but I'm trying to figure out if there's a way I can manage either the bound @State variable from the store or some other solution so the state of my UI is coming 100% from my store.

In the past in Redux, I've had situations that are more like:

  func map(state: AppState, dispatch: @escaping DispatchFunction) -> Props {
    return Props(
      isVisible: someComplicatedLogic(state)
    )
  }

isVisible is derived from the state and should update / recompute when state changes.

Any recommendations how to handle this situation in a SwiftUIFlux'y way?

levous commented 4 years ago

There shouldn't be anything specific to do with SwiftUIFlux.
this article explains some changes in SwiftUI: https://swiftui-lab.com/advanced-transitions/

try

      if props.isVisible {
        Text("I'm visible!").transition(
          AnyTransition.opacity.animation(.easeInOut(duration: 1.0))
        )
      }