17

While testing out SwiftUI, I've found that AsyncImage does not work well while animating a transition. It seems to settle on its final position of the transition before the rest of the UI has moved there, making the animation seem weird or off.

My main question is: is there any way to access the SwiftUI animation of the AsyncImage and make it work with other animations elsewhere in the app?

The weird part is that, if I change it to some other view (that doesn't have animations), the transition behaves correctly, so I believe that the root of the problem is something to do with AsyncImage's default animation for changing between its phases (loading, failed or loaded).

The overlay that is presented is described as such:

    if isBottomSheetVisible {
                VStack(alignment: .leading) {
                    AccountSelectorHeader()
                    ForEach(accounts) { account in
                        AccountRow(
                            account: account,
                            isLast: accounts.last == account
                        )
                    }
                }
                .padding(.bottom, 24)
                .background(Color(.tableViewHeaderBackgroundColor)
                                .cornerRadius(24, corners: [.topLeft, .topRight])
                                .edgesIgnoringSafeArea(.bottom)
                )
                .transition(
                    .move(edge: .bottom)
                )
            }

And each image is only a standard AsyncImage inside the AccountRow view:

    AsyncImage(url: URL(string: account.image)) {
            $0
                .resizable()
                .clipShape(Circle())
        } placeholder: {
            ProgressView()
        }
1
  • FWIW- I was having a similar issue and when I replaced the AsyncImage with a custom view that loaded an image, it animated properly, so seems like a bug in AsyncImage Commented May 11, 2022 at 13:58

2 Answers 2

12

I faced a similar issue and it worked fairly well if you use the init(url:scale:transaction:content:).

With the code below I got the image move in with the sheet and on disappear it didn't move but was removed as the sheet obscured it:

AsyncImage(
            url: URL(string: url),
            transaction: Transaction(animation: .default)
        ) { phase in
            switch phase {
            case .success(let image):
                image
                    .resizable()
            default:
                Image("defaultImage")
                    .resizable()
            }
        }
Sign up to request clarification or add additional context in comments.

2 Comments

If this answer doesn't work try adding .drawingGroup() to AsyncImage so that it is rendered as a single View
Thanks! This same issue appears in loading async images through Kingfisher and SDWebImageSwiftUI. While the above answer only works for AsyncImage, .drawingGroup() words for all of them. However, it renders slightly slower, so I'm only using it when the image needs a transition.
0

That's indeed weird, just tried with an own implementation of asyncImage and it has a similar behaviour, perhaps it is easier for you to fix it from there: Simple iOS13 AsyncImage. I will take a look to it too if I have time.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.