faberNovel / DynamicOverlay

A SwiftUI library that makes easier to develop overlay based interfaces, such as the one presented in the Apple Maps app.
MIT License
210 stars 20 forks source link

Transitioning between notches #9

Closed chadobado closed 3 years ago

chadobado commented 3 years ago

Is there a suggested approach to handle/interpolate notch changes during transition?

Use cases being to:

  1. Change overlay subviews based on actual or expected notch change during transition (dragged or released)

  2. Interpolate values based on fractional change during transition ex: expanding the width of the overlay while going from preview->fullScreen notches.

Tried approaches:

.notchChange is handled after the the transaction completes so doesn't help here.

.onTransition returns the height/transaction but not the fractional value.

Since the mapper and internal GeometryReader proxy (via environment) are internal I haven't found a way to easily convert between height and a fractional value or determine the target notch during current transition.

What does work is wrapping everything in another GeometryReader to capture the height and manually calculate the fractional change between notches (rescaling as needed) which seems like quite a bit of duped work considering what's happening under the hood.

Happy to provide code examples if helpful.

Feedback appreciated thanks.

gaetanzanella commented 3 years ago

Hi @chadobado thank you for the suggestions!

I added some details to the translation in the new 1.0.0-beta.4 version:

public extension MagneticNotchOverlayBehavior {

    /// The attributes of a translation
    struct Translation {
        /// The current overlay height.
        public let height: CGFloat
        /// The transaction associated to the translation.
        public let transaction: Transaction
        /// The overlay translation progress (from 0.0 to 1.0).
        public let progress: Double
        /// The overlay container size.
        public let containerSize: CGSize
        /// returns the height of the given notch.
        public func height(for notch: Notch) -> CGFloat
    }
}

Tell me if it's enough!

chadobado commented 3 years ago

Thanks @gaetanzanella, big improvement!

In my early testing I'm noticing some pretty painful performance hits with visible judder especially when containing more complex subviews (100%).

Have you noticed this, or have any suggestions?

EDIT: It appears the performance hit is due to one of my sub views using TabView w/ PageTabViewStyle, which has documented performance issues. Will circle back if it persists.

Thought it might be due to the frequency onTranslation is pushing to @State var and forcing the View to redraw. I quickly took a stab at having onTranslation push to a PassthroughSubject so that my ViewModel could throttle the requests but it had a negligible improvement.

Thanks again

gaetanzanella commented 3 years ago

Yes I already faced similar performance issues in prior versions. If it is still the case, could you provide a sample code?