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()
}
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()
}
}