Hi there, I'm getting this animation flickering wh...
# compose-ios
m
Hi there, I'm getting this animation flickering when expanding a CMP view inside a SwiftUI scroll view that looks like this:
Copy code
ScrollView {
    VStack {
        cmpView1

        cmpView2

        swiftView1

        swiftView2

        // ...
    }
}
I'm using Compose 1.8.0-rc01, and this is how I'm creating the animation:
Copy code
AnimatedVisibility(
    modifier = Modifier.fillMaxWidth(),
    visible = state.isVisible,
    enter = fadeIn(animationSpec = tween(durationMillis = 500)) + expandVertically(
        expandFrom = <http://Alignment.Top|Alignment.Top>,
        animationSpec = tween(durationMillis = 500)
    ),
    exit = fadeOut(animationSpec = tween(durationMillis = 500)) + shrinkVertically(
        shrinkTowards = <http://Alignment.Top|Alignment.Top>,
        animationSpec = tween(durationMillis = 500)
    )
) {
    // Banner
}
Any possible solutions to make it look nicer?
The first two views are CMP, and as you can see in the screen recording, their inner content kind of vibrate while expanding
c
Is this a release build or a debug one? Release builds usually have better performance
m
It's release unfortunately, published by our CI/CD through TestFlight. I was also experiencing it when building locally but wanted to wait until getting a final build to discard debug performance issues too 😞
☹️ 1
c
Since your outermost layer is swiftUI, I would try animating the item heights from swiftUI by wrapping the Compose items with a swiftUI wrapper. This way swiftUI has to sync with swiftUI directly, and not just react to the height change of something it has no idea about
m
What I like about this approach is that the responsibility to decide whether to show the view is completely self-contained in KMP. The ViewModel inside KMP (not exposed to the iOS layer) decides to show the view based on inner conditions and observing some domain Flows. I could potentially expose the flow through KMP, observe it in the SwiftUI ViewModel and decide to show or hide the view based on that, but I find that approach not as nice as I need to expose more stuff to the iOS layer. Is this in line with the approach you are suggesting, or am I missing something? This is how an entry to a CMP view would look in SwiftUI for our project, which might render or not render at all based on inner conditions:
Copy code
VStack {
    CmpEntryPoint(
        feature: RandomFeature.Banner(
            param1: randomParam,
            navigateToSomewhere: {
                // Navigate in Swift 
            }
        ),
        fillScreenHeight: false
    )
    //...
}
Btw, it is worth mentioning that this CmpEntryPoint when used with
fillScreenHeight: false
uses a custom implementation that mesures a Compose view and passes its height to SwiftUI, suggested by @John O'Reilly in his blog post: https://johnoreilly.dev/posts/swiftui-component-compose-ios/
j
I should add that it's been 2 years since that article so things have possibly changed.....I need to review it at some point as well
m
When I implemented it in October last year I did not find any other available solutions than yours 😅 So far it has been working great, thanks for the post!
👍 1
c
@Marcel I would not start to refactor it properly. At first I would just try out the hypothesis just by hacking a Proof of Concept together. If driving the animation from the swiftUI side helps with the jankiness, then it is worth refactoring. If not, then you might need to accept it or try another approach, or change the animation to something that looks smoother.
c
unrelated... but is that graph CMP (vico)? if so... is that a library or something you created?
m
That is indeed CMP, I used KoalaPlot
Thanks @Csaba Szugyiczki, I'm moving towards that direction, removing the animation from CMP and leaving it up to the platform to display or hide the component with the right animation. It's unfortunate I cannot drive it all from CMP! 😪
c
It is just a guess, that it might be more performant. If you have the chance please let us know if it helped or not.
m
I switched yesterday to leave it to SwiftUI to handle the appear animations. It's not as smooth as the Compose Android version, but it looks better than what we had earlier with the CMP version, that one felt buggy. Probably it can be improved somehow with a different SwiftUI approach, but for now I'm keeping it like this.
c
It definitely looks much smoother!
🙏 1