Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Animators in SwiftUI #24

Open
matthewcheok opened this issue Nov 13, 2022 · 2 comments
Open

Animators in SwiftUI #24

matthewcheok opened this issue Nov 13, 2022 · 2 comments

Comments

@matthewcheok
Copy link

matthewcheok commented Nov 13, 2022

Really exciting that we're able to use Wave in SwiftUI. Couple of questions:

@jtrivedi
Copy link
Owner

Hey @matthewcheok, thanks for posting this! Glad you're excited about SwiftUI + Wave.

I'm definitely not a SwiftUI expert, so I have a few questions:

  • Did you see multiple SpringAnimator instances being created in the SwiftUI sample app, when not marked with @State? I didn't see this behavior with or without @State. Perhaps I'm missing something?

  • I'm not too familiar with TimelineView. Can you help me understand what the benefit of using it would be? It's also worth noting that Wave's animation updates are already tied to the display's render cycle via a display link, so we shouldn't be re-rendering more than necessary.

@matthewcheok
Copy link
Author

Did you see multiple SpringAnimator instances being created in the SwiftUI sample app, when not marked with @State? I didn't see this behavior with or without @State. Perhaps I'm missing something?

I don't think its an issue in this specific instance but in general SwiftUI views are meant to be light-weight and could be instantiated many times. @State is used to persist values between render cycles. This could be observed if SwiftUIView was embedded in a parent view that has changing state, for example.

I'm not too familiar with TimelineView. Can you help me understand what the benefit of using it would be? It's also worth noting that Wave's animation updates are already tied to the display's render cycle via a display link, so we shouldn't be re-rendering more than necessary.

AFAIK TimelineView allows views to update with an explicit cadence (one of which is the animation schedule which perhaps works like CADisplayLink) vending a context (with the current date) which could be used to drive an animation. I think the nice thing about this is that the content that is driven by this view seems well encapsulated whereas the animator changing state could potentially trigger updates in an arbitrarily large view hierarchy.

Another potential alternative way to drive the animation is to make the animator an ObservableObject with the value being @Published - this avoids the consumer having to hold on to their own @State that mirrors the value property of the animator or having to configure the update handler. The view might then look something like this:

struct SwiftUIView: View {
  @StateObject var animator = SpringAnimator(...)

  var body: some View {
    ZStack { ... }
      .offset(x: animator.value.x, y: animator.value.y)
  }
}

While neither are problems in your particular code example, I'd suggest the first change in terms of best practices.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants